迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

C++ 中错误 Function Returns the Address of a Local Variable

作者:迹忆客 最近更新:2023/08/20 浏览次数:

根据作用域,C 和 C++ 中的变量分为局部变量和全局变量。 虽然可以从程序的任何部分访问全局变量,但局部变量却不然。

因此,当代码中涉及各种函数时,谨慎使用它们很重要。 否则,您可能会遇到局部变量地址返回错误。

让我们讨论一下为什么会出现这个错误以及如何修复它。


C++ 中 Function Returns the Address of a Local Variable 错误

要了解函数返回局部变量地址错误的原因和可能的修复方法,我们必须知道局部变量是如何工作的。 我们先讨论一下这个问题。

C++ 中局部变量的行为

局部变量是在函数内部定义的变量,不能在该特定函数外部使用。 换句话说,它只存在于定义它的函数内部,不能从程序的任何其他部分访问。

这里有一个非常重要的信息 - 一旦函数结束执行,局部变量的生命周期就会被破坏。

看这个例子。 这里,变量cost在函数demo()内部声明; 因此,其范围仅限于此功能。

在主块内,我们尝试访问这个局部变量,因此,程序遇到错误。

这本质上就是局部变量的工作原理。

#include<iostream>
using namespace std;

void demo()
{
    int cost = 5000;
    cout << "The variable cost is local to the demo function." << endl;
}
int main()
{
    int cakes = 10;
    demo();
    cout << "Payable amount: " << cost;

}

输出:

In function 'int main()':
error: 'cost' was not declared in this scope
     13 |     cout << "Payable amount: " << cost;
        |                                   ^~~~

现在您知道在其范围之外使用局部变量是非法的。 我们来讨论一下为什么会出现错误 function returns the address of the local variable


C++中 function returns the address of the local variable 的原因

函数返回局部变量的地址错误通常发生在使用函数和局部变量时。 正如我们无法访问其定义范围之外的局部变量一样,我们也无法在该范围之外访问其地址。

像这样看。 当您尝试访问定义范围之外的局部变量时,您会收到“variable not declared in this scope”错误,如上面的示例所示。

但是,如果您尝试访问定义范围之外的局部变量的地址,则会出现 function returns the address of the local variable 的错误。

这就是发生这种情况的原因。

我们知道,一旦函数完成执行,局部变量就会被销毁。 这意味着返回局部变量地址的指针现在指向一个甚至不存在的对象。

指向局部变量的指针不能超出局部变量所在的函数。 但是当这种情况发生时,我们可以说指针变成了悬空指针,因此,我们得到函数返回局部变量地址的错误。

此错误可能在多种情况下发生。 让我们一一讨论。


C++ 中 function returns the address of the local variable 错误的示例

虽然所有此类代码运行到函数中返回局部变量地址错误的原因与上面讨论的相同,但让我们详细看几个示例。

函数返回指向局部变量的指针

看看下面给出的代码。 我们有一个名为 demo() 的函数,它接受两个整数值并将它们相加。

该函数将总和存储在变量 cost 中,然后返回该变量的地址。 但是当您运行此代码时,您会得到局部变量的地址返回错误。

这里请注意两件事。

  1. 可变成本在函数 demo() 内定义; 因此,其范围仅限于此功能。 它是一个局部变量。
  2. return 语句返回一个指针,该指针具有局部变量 cost 的地址。

我们知道,一旦函数 demo() 完成执行,其中存在的局部变量 cost 也会被销毁。 这意味着之前指向变量成本地址的指针现在开始指向我们不再拥有的内存中的位置。

因此,我们得到这个错误。

#include<iostream>
using namespace std;

int* demo(int cherry, int pie)
{
    int cost = cherry + pie;
    return &cost;
}

int main(){
    int* ans = demo(100, 20);
}

输出:

In function 'int* demo(int, int)':
warning: address of local variable 'cost' returned [-Werturn-local-addr]
    7 |    return &cost;
      |           ^~~~~
note: declared here
    6 |    int cost = cherry + pie;
      |        ^~~~

让我们看看如何解决这个问题。 问题在于返回地址是局部变量的地址; 因此,动态内存分配将有助于解决这个问题。

在主块内,我们动态定义可变成本并分配内存。 然后,我们将此变量作为参数传递给 demo() 函数。

#include<iostream>
using namespace std;

int* demo(int cherry, int pie, int* cost)
{
    *cost = cherry + pie;
    return cost;
}

int main(){
    int *cost = new int;
    cost = demo(100, 20, cost);

    cout << "The total is stored at address: " << cost;
}

输出:

The total is stored at address: 0x55c7997a7eb0

当我们运行这段代码时,这次我们得到了正确的输出。 这是因为变量 cost 不再是局部变量,因为它是在 demo() 函数外部声明的。

函数返回作用域为本地的字符串

看下面的代码片段。 在这里,我们将名称作为用户的输入,并使用 checkname() 函数检查它是否有效。

checkname() 函数中,我们定义了一个名为 fullname 的字符串,如果通过检查条件则返回它。 但代码中遇到了函数返回局部变量地址的错误。

这就是发生这种情况的原因。

我们有一个名为 fullname 的字符串,其范围仅限于 checkname() 函数。 另外,字符串就像一个数组,在传递之前先被简化为指针。

当我们返回主块时,函数的局部变量将被销毁,因为控件已移出该函数。

这就是我们收到错误的原因。

#include<iostream>
#include<cstring>
using namespace std;

char* checkname()
{
    char fullname[20];
    //....
    //......
    //....
    if((strlen(fullname)) >=4 && (strlen (fullname)) < 30)
    {
        return fullname;
    }
    else
    {
        return NULL;
    }
}

int main(void)
{
    char name[20];
    cout << "Enter name:" << endl;
    name = checkname();
}

输出:

warning: address of local variable 'fullname' returned [-Wreturn-local-addr]

要解决此问题,请不要返回数据,而是将其传递给函数,如下所示:

#include<iostream>
#include<cstring>
using namespace std;

void checkname(char *fullname)
{
    if((strlen(fullname)) >=4 && (strlen (fullname)) < 30)
    {
        cout << "Success";
    }
    else
    {
        cout << "In else block";
    }
}

int main(void)
{
    char name[20];
    cout << "Enter name:" << endl;
    checkname(name);
}

输出:

Enter name:
In else block

看,这次代码运行良好,并且由于我们没有接受任何输入,因此我们进入了 else 块。

虽然这解决了问题,但更可靠的解决方案是将内存动态分配给变量 fullname,如下所示:

char *fullname = malloc (sizeof (char) * the_size);
...
....
return fullname;

当我们动态分配内存时,它是从堆中分配的,堆的生存期直到整个程序执行完毕为止。 因此,当我们现在返回变量fullname时,我们得到了malloc定义的地址,并且代码运行良好。

此外,完成后释放内存是避免内存泄漏的好习惯。


总结

本文讨论了C++中函数返回局部变量地址的错误。 我们了解了局部变量的行为方式以及尝试在其范围之外访问它们是非法的。

我们在一些用例的帮助下了解了此错误的原因以及可能的解决方案。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Arduino 中停止循环

发布时间:2024/03/13 浏览次数:444 分类:C++

可以使用 exit(0),无限循环和 Sleep_n0m1 库在 Arduino 中停止循环。

Arduino 复位

发布时间:2024/03/13 浏览次数:315 分类:C++

可以通过使用复位按钮,Softwarereset 库和 Adafruit SleepyDog 库来复位 Arduino。

Arduino 的字符转换为整型

发布时间:2024/03/13 浏览次数:181 分类:C++

可以使用简单的方法 toInt()函数和 Serial.parseInt()函数将 char 转换为 int。

Arduino 串口打印多个变量

发布时间:2024/03/13 浏览次数:381 分类:C++

可以使用 Serial.print()和 Serial.println()函数在串口监视器上显示变量值。

Arduino if 语句

发布时间:2024/03/13 浏览次数:123 分类:C++

可以使用 if 语句检查 Arduino 中的不同条件。

Arduino ICSP

发布时间:2024/03/13 浏览次数:214 分类:C++

ICSP 引脚用于两个 Arduino 之间的通信以及对 Arduino 引导加载程序进行编程。

使用 C++ 编程 Arduino

发布时间:2024/03/13 浏览次数:127 分类:C++

本教程将讨论使用 Arduino IDE 在 C++ 中对 Arduino 进行编程。

Arduino 中的子程序

发布时间:2024/03/13 浏览次数:168 分类:C++

可以通过在 Arduino 中声明函数来处理子程序。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便