7

次のステートメントがあるとします。

int *x = new int;

この場合、ヒープにメモリを動的に割り当てました。つまり、オブジェクトのreservedメモリ アドレスを取得しました。int

その後、私は次のようにしました:

delete x;

つまりfreed up、ヒープ上のメモリ アドレスです。

その後、私は再び次のことをしたと言います:

int *x = new int;

x削除される前にヒープで指していたのと同じ古いメモリアドレスを指しますか?

以前にこれを行ったとしたらどうなりますかdelete

x = NULL;

そして、これを行いました:

int *x = new int;

古いもの以外xヒープ上のメモリアドレスを指しますか?

ありがとう。

4

6 に答える 6

11

最初のケースでは、同じメモリ ブロックを再度取得する可能性がありますが、確実ではありません。

2 番目のケースでは、メモリを解放していないため、別のアドレスで別のメモリ ブロックを取得することがほぼ確実です。C++ のガベージ コレクタがあります。これらのいずれかを使用した場合、ポインターを NULL アウトしてから (以前に割り当てられたメモリ ブロックにアクセスできなくなった)、再度割り当てを要求するまでの間にガベージ コレクターが実行される可能性があります。このような場合、同じメモリ ブロックを再度取得できます。もちろん、ガベージ コレクターがなければ、メモリ リークが発生するだけなので、どのような場合でもこれを行う方法はありません。

于 2011-01-29T09:32:50.930 に答える
3

あなたが求めているのは(C / C ++標準に従って)完全に未定義であり、実装に依存します。

お使いのバージョンのコンパイラでこれを簡単にテストできるはずです。

ただし、この動作の結果には依存しないでください。これは、いつでも、どの OS でも、コンパイラのアップグレードによっても変わる可能性があるためです。

何が起こるかについては、プログラムに他のスレッドが同時に割り当てられていない限り、同じアドレスを取得する可能性が最も高いでしょう。ただし、コンパイラの特定の malloc 実装が異なるスレッドに異なるヒープを使用することを決定した場合は、同じアドレスを取得する可能性があります (これはパフォーマンスの点で優れています)。

于 2011-01-29T09:33:06.743 に答える
2

削除する前にこれを行うと:

x = NULL;

それはメモリリークです。何の役にも立たないメモリを失い、そのアドレスを失ったために解放できません。(ヌルポインタを削除できますが、何もしません)

これを長時間行うと、すべてのメモリが無駄になるため、システムがクラッシュしたり、許容範囲を超えて速度が低下したりする可能性があります。(ディスク上のスワップを使いすぎているなど...など...)

削除後にまったく同じ新しいアドレスを取得してから、もう一度新しいアドレスを取得することを期待しないでください。時々、ランダムに発生する可能性がありますが。

于 2011-01-29T09:31:56.360 に答える
1

いいえ、そのような保証はありません。これは、メモリ要求を満たすために使用されるアロケータに完全に依存します。ただし、C++ は強力な獣であるため、new 演算子をオーバーライドしましょう。特定の方法でメモリを提供するカスタム アロケータ (メモリ管理) を構築できます。これは非常に便利な場合があります。

于 2011-01-29T09:28:59.817 に答える
1

いいえ、second から返されたポインターはnew int;、有効な書き込み可能なアドレス範囲内の任意の場所を指すことができます。以前に割り当て解除された領域が使用されるという保証はありません (実際には、ヒープ マネージャーが後で実際のメモリを解放することを選択する可能性があるため、ほとんどの場合は使用されない可能性があります)。

于 2011-01-29T09:31:46.557 に答える
1

1)解放した後、同じ変数を使用して再度割り当てた場合、同じメモリチャンクを取得できるという保証はありません。new がどのように実装されるかを考えてみてください。カスタム アロケータを使用しても、想像できるあらゆる方法で実行できます。また、他のスレッドが free() と new() 呼び出しの間に new を使用し、メモリを「盗んだ」可能性があります

2) やらないでください。参照を失っており、NULL ポインターに削除演算子を適用しても何もしません。したがって、他の変数に参照を保存しないと、リソース リークが発生する可能性があります。new を再度呼び出すと、最初の new() によって付与された領域の割り当てが誰も解除されていないと仮定して、間違いなく別の場所に割り当てられます

于 2011-01-29T09:32:49.473 に答える