21

重複の可能性:
C++ の削除 - オブジェクトは削除されますが、データには引き続きアクセスできますか?
ローカル変数のメモリにスコープ外でアクセスできますか?

deleteで割り当てられたメモリを解放したいときに実際に何が行われるのかわかりませんnew。C++ Premiere book では、次のように書かれています。

これにより、ps ポインタが指すメモリが削除されます。ポインター ps 自体は削除されません。たとえば、ps を再利用して、別の新しい割り当てを指すことができます。new の使用と delete の使用のバランスを取る必要があります。そうしないと、メモリ リークが発生する可能性があります。つまり、割り当てられたメモリが使用できなくなります。メモリ リークが大きくなりすぎると、より多くのメモリを求めるプログラムが停止する可能性があります。

したがって、私が理解deleteしているように、ピンターが指すメモリ内の値を削除する必要があります。しかし、そうではありません。これが私の実験です:

int * ipt = new int;   // create new pointer-to-int

cout << ipt << endl;   // 0x200102a0, so pointer ipt points to address 0x200102a0
cout << *ipt << endl;  // 0, so the value at that address for now is 0. Ok, nothing was assigned
*ipt = 1000;     // assign a value to that memory address
cout << *pt << endl;   // read the new value, it is 1000, ok
cout << *((int *) 0x200102a0) << endl;   // read exactly from the address, 1000 too

delete ipt;   // now I do delete and then check
cout << ipt << endl;  // 0x200102a0, so still points to 0x200102a0
cout << *ipt << endl;  // 1000, the value there is the same
cout << *((int *) 0x200102a0) << endl;    // 1000, also 1000 is the value

では、実際には何deleteをするのでしょうか?

4

6 に答える 6

61

メモリは、物を入れる箱がたくさんある大きな倉庫だと考えてください。あなたが「新品」と呼ぶと、倉庫のスタッフがあなたのニーズに合った十分な大きさの未使用の箱を見つけ、その箱をあなたの所有物として記録し (他人に譲渡されないように)、その箱の番号を教えてくれます。あなたのものをそれに入れます。この数字が「ポインタ」になります。

ここで、そのポインタを「削除」すると、逆のことが起こります。倉庫のスタッフは、この特定のボックスが再び利用可能であることに気付きます。実際の倉庫のスタッフとは対照的に、彼らはボックスで何もしていません。そのため、「削除」後に調べてみると、古いものが表示される場合があります。または、その間にボックスが再割り当てされた場合、他の人のものを見るかもしれません。

技術的には、一度プールに戻したボックスの中を見ることは許可されていませんが、これは鍵やガードのない奇妙な倉庫なので、好きなことをすることができます. ただし、ボックスの新しい所有者との間で問題が発生する可能性があるため、ルールに従うことが期待されます。

于 2012-07-22T18:52:54.990 に答える
9

ステートメントundefined behaviorの後にポインターを逆参照するとすぐに、実験が行われます。deleteすべてが起こる可能性があるため、実験はかなり無意味になります。

delete(ではない) は何をしdelete[]ますか? 引数が指すストレージの割り当てを解除します。これにより、その場所に格納されているオブジェクトのデストラクタが実行されます。削除されたストレージにアクセスすると、未定義の動作がトリガーされます (多くの場合segmentation fault)。メモリが実際にオペレーティング システムなどに返されるという保証はありません。

于 2012-07-22T18:45:46.570 に答える
6

オペレーターは、オペレーターdeleteを使用して以前に割り当てられたメモリーを解放しますnew。これは、たとえば、プログラムの後半で別の用途がある場合などに、システムがメモリを使用できるようになったことを意味しますnew。ただし、メモリ内のデータはクリアされません。ポインターは引き続きメモリ内の同じアドレスを指しますが、そのブロックにアクセスすると、未定義の動作が発生します。

ポインターをing した後にNULL(またはnullptrC++11 で)ポインターを設定することをお勧めします。delete後続deleteの は無害です。

于 2012-07-22T18:47:18.753 に答える
5

-ing後のポインターの逆参照deleteは未定義の動作であるため、何が起こる可能性があります。

通常、delete後で再利用できるようにメモリを解放済みとしてマークしますが、これは複雑なトピックです。

経験則: 絶対にnewand を直接使用しないでください (何らかの理由で標準に欠けている のdelete実装を除く)。make_uniqueRAII を使用します。

于 2012-07-22T18:47:28.410 に答える
5

deleteを介した後のリクエストでメモリを使用できるようにしますnew。コンテンツにスクランブルをかけるかどうかは未定義です。内容はそのままにしておく方が早いので、リリースモードではおそらくメモリがまだ「使用可能」に見えるでしょう。デバッグ モードでは、マジック ナンバーでスクランブルされる可能性があります。

ここで経験していることは、C++ では「未定義の動作」と呼ばれます。この場合、未定義の動作は、有効期間が終了した後にメモリの一部にアクセスすることによって発生します。やらないでください。

于 2012-07-22T18:48:29.313 に答える
4

deleteメモリをシステムに返します。基本的に、プログラム用に予約されていません。これは、メモリ内の値がすぐに上書きされることを意味するわけではありませんが、実行後はいつでも上書きされる可能性deleteがあります。ほとんどの場合、同じメモリが再割り当てされ、独自のプログラムで将来使用されます。

于 2012-07-22T18:48:14.393 に答える