1

在以下代码中,getObj()函数返回对本地对象的引用。这显然是非常糟糕的,因为当函数返回时对象被销毁(ctor 和 dtor 输出强调对象的生命周期)。正如预期的那样,编译器(gcc44)给出了相应的警告。

#include <iostream>

class Blah {

private:
    int a_;

public:
    Blah(int a) : a_(a) { std::cout << "Constructing...\n"; }
    ~Blah() { std::cout << "...Destructing\n"; }
    void print() { std::cout << a_ << "\n"; }
};

Blah& getObj() 
{
    Blah blah(3);
    return blah; // returning reference to local object
}

int main()
{
    Blah& b = getObj();
    b.print(); // why does this still output the correct value???

    return 0;
}

然而,调用print()明显被破坏的对象仍然会打印出私有变量的正确值a_。这是输出:

建设中...
...破坏
3

怎么会这样?我本来希望所有对象数据也会被销毁。

4

3 回答 3

6

它被称为未定义的行为。任何事情都有可能发生。你所看到的只是“任何事情”的一个子集。

于 2013-02-27T14:33:10.540 回答
0

为什么会破坏数据?恐怕你对正在发生的事情的心理模型显然是不正确的。当一个对象从堆栈或堆中释放时,所发生的一切就是它所存储的内存现在被标记为可以使用。数据仍然存在,直到发生某些事情来覆盖它。

于 2013-02-27T14:36:43.000 回答
0

销毁只是意味着将内存归还给它的原始所有者(操作系统)。它不会被删除或覆盖。某些操作系统允许您读取任何内存,因此您可以读取它,如果幸运的话,没有其他人获得这块内存并且您的价值仍然存在。请注意,不能以任何方式保证幸运,您的程序可能会崩溃和烧毁。

于 2013-02-27T14:37:46.113 回答