首页 文章

返回局部变量的引用[重复]

提问于
浏览
1

这个问题在这里已有答案:

在以下代码中,演示了两个函数 . f1()返回函数作用域中初始化局部变量的引用,f2()返回函数作用域中初始化局部变量的值 .

f2()预计会运行良好,因为本地初始化变量 . 值从堆栈传递到main .

f1()不会起作用,因为局部变量的引用在函数范围之外是无用的 . 但是,两个函数的输出似乎都没问题 .

这是测试代码;

#include <iostream>
using namespace std;

// function declarations
int& f1();
int f2();

int main()
{
    cout << "f1: " << f1() << endl; // should not work!
    cout << "f2: " << f2() << endl; // should work

    return 0;
}

int& f1()       // returns reference
{
    int i = 10; // local variable

    return i;   // returns reference
}

int f2()        // returns value
{
    int i = 5;  // local variable

    return i;   // returns value
}

输出如下;

f1: 10
f2: 5

为什么f1()工作正常,即使f1()返回局部变量的引用?

2 回答

  • 7

    访问范围超出范围的局部变量是未定义的行为 . 未定义的行为意味着程序可能工作,它可能是段错误,它可能打印垃圾值,一切 .

    低级别的原因1是局部变量位于堆栈上 . 堆栈属于进程的可写地址空间(至少在大多数(如果不是全部)操作系统上都是如此) . 该程序可能会像它想要的那样写入它 . However ,写入堆栈是C不支持的 . C只定义局部变量,而不是调用帧或返回地址 . 它驻留在更高级别的抽象上 . 支持直接写入我所知道的堆栈的唯一语言是Assembly .


    1无论如何,C标准都没有规定这个原因 .

  • 5

    欢迎来到 undefined behaviour

    这就是你在做什么 . 您访问已超出范围的变量 . 但是,可能是系统没有在已经存在的值上写入某些东西,这解释了行为 .

    这就是为什么在实际代码中找到这样的逻辑错误很难的原因 . 因为您可能(非)幸运且变量具有正确的值(在该特定执行中) .

    因此, f1() 的返回值是对超出范围的内容的引用,而 f2() 的返回值是该函数的局部变量的副本,这是正常的 .


    但是,下降编译器应警告您这一点,并发出以下警告:

    警告:引用本地变量'i'返回[-Wreturn-local-addr]

    请在编译器中使用 Enable 警告标志 . :)

相关问题