2

重複の可能性:
C++ の削除 - オブジェクトは削除されますが、データには引き続きアクセスできますか?

次のコードを検討してください:-

#include <iostream>
class Test
{
public:
    int k=10;
};

int main(int argc, const char * argv[])
{
    Test *t = new Test();
    delete t;
    //t1 = NULL;
    t->k=50;
    printf("\n%d",t->k);
    return 0;
}

その出力は50削除tされますが。なぜクラッシュしないのですか?Mac OS x で Xcode を使用しています。

4

3 に答える 3

2

「delete」は、(デストラクタの呼び出しは別として) new を使用して以前に割り当てられた sizeof(Test) のメモリ ブロックが使用されなくなり、ヒープ マネージャがそのメモリ ブロックを自由に使用できることをヒープ マネージャに通知するだけです。 .

同じコードがいつ例外を引き起こす可能性があるかについて、シナリオを示してみましょう。

ヒープ マネージャーが仮想メモリ マネージャーから取得した新しいメモリ ページに、ヒープ マネージャーによってメモリ ブロックが割り当てられたとします。これは、以前に割り当てられたページの空き領域が他に見つからなかったためです。そして、削除が完了すると、ヒープ マネージャーは、メモリ ページに割り当てられた唯一のブロックが解放されたことを検出するため、メモリ ページを仮想メモリ マネージャーに解放することを決定する可能性があります。そして、コードが仮想メモリに存在しないページのメモリにアクセスすると、エラーが発生します。

もちろん、ヒープ管理の実装に関する十分な知識があれば、他のシナリオを思いつくことができます。

于 2012-11-05T05:42:19.567 に答える
1

あなたは(不)運が悪いからです。未定義の動作を呼び出しています。考えられる未定義の動作の 1 つは、「期待どおりに動作する」ことです。しかし、あなたの期待は疑わしいです。delete とその関数がメモリを割り当てる use の間に関数呼び出しを追加すると、不適切な割り当てで他のデータを完全に破壊する可能性があります。

未定義の動作はクラッシュする必要はありません...またはすぐにクラッシュする必要はありません。しかし、それを呼び出すと、特に大きなプログラムでは、長期的には問題が発生することがよくあります。

于 2012-11-05T05:24:09.653 に答える
0

これは、何も期待すべきではない未定義の動作です。ただし、メモリはおそらくまだ書き込まれておらず、空きとしてマークされているだけで、最終的には上書きされるため、おそらく機能しています。ポインターを に設定することをお勧めします。NULLこのような落とし穴を回避するには、ダングリング ポインターの問題を参照してください。

于 2012-11-05T05:23:29.167 に答える