从值返回创建const左值引用:它是如何工作的?

时间:2012-04-13 18:10:19

标签: c++ memory-management g++ stack rvalue-reference

我从here得知,const引用可以由函数返回的值返回。但是现在我问自己:在哪里放置这个对象,这样它是安全的,不会被未来函数调用的堆叠覆盖?

考虑以下代码:

#include <iostream>
using namespace std;

struct A{};

A returnsmt(){
    int avariable;
    cout<<"returnsmt stack: "<<&avariable<<endl;
    return A();
}

const A& proxyreturnsmt(){
    int avariable;
    const A& middle=returnsmt();
    cout<<"proxyreturnsmt stack: "<<&avariable<<" A ptr: "<<&middle<<endl;
    return middle;
}

int main(){
    int avariable;
    const A& a=proxyreturnsmt();
    cout<<"main stack: "<<&avariable<<" A ptr: "<<&a<<endl;
}

现在,main知道它将从堆栈的对象创建引用是不可行的,所以诀窍不能是它将隐藏指针传递给一个自己的免费堆栈桶。 g ++上的这段代码打印出来:

returnsmt stack: 0x7fff3718bc0c
proxyreturnsmt stack: 0x7fff3718bc28 A ptr: 0x7fff3718bc2f
main stack: 0x7fff3718bc4c A ptr: 0x7fff3718bc2f

所以看起来,如果堆栈向下增长,那么对象所在的位置实际上是proxyreturnsmt的堆栈。如果得到这个参考后,你怎么会遇到麻烦,你打电话,让我们说function_with_big_stack_alloc,所以肯定会收回旧proxyreturnsmt的堆栈用于新用途?

1 个答案:

答案 0 :(得分:0)

程序显示未定义的行为。在proxyreturnsmt中,将middle绑定到临时对象。该临时对象的生命周期仅在middle超出范围时才会延长。

然后返回对middle的引用;但是它引用的对象在函数返回时被销毁。因此,在main中,您将a绑定到调用proxyreturnsmt的结果,a是一个悬空引用(它引用的对象不再存在)。< / p>

当您尝试使用引用时(通过获取不再存在的引用对象的地址),程序将显示未定义的行为。