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 に答える