6

を使用してヒープ上にメモリを割り当てる:この場合C++、私は次の文がある場合は、「新しい」

int *x = new int;

を、私は動的にヒープ上にメモリを割り当てられています。言い換えれば、私は今intオブジェクトのメモリアドレスがreservedです。

delete x;

私は、ヒープ上のメモリアドレスをfreed upことを意味します

セイはそのことの後に、私は次のよう作られました。が削除される前に、それがヒープで指さ同じ古いメモリアドレスに

int *x = new int;

ウィルxポイント:

言ってやるが、その後私は再び次のことをやりましたか?その後、

x = NULL;

そして、このでした:

私はdelete前にこれをしなかった場合はどうヒープより上のAAのメモリアドレスに

int *x = new int;

ウィルxポイントを古いもの?

ありがとうございました。

+1

ポインタをNULLに設定するだけで、それを削除しません。 'new int'を実行すると、古いメモリはまだ使用されます(ポインタなしではメモリリークです)。もちろんnewは常に* new *アドレスを指しますので、名。 –

答えて

1

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

+0

例を挙げてください。あなたは 'new'を使わずにどのようにメモリを割り当てるのですか?カスタムアロケータは何のために使われますか? –

+0

カスタムアロケータは、固定量のシーケンシャルメモリを提供するために使用できます。パフォーマンスは賢明で、一般的にはゲームでは素敵なシーケンシャルなメモリアクセスパターンが必要です。ガベージコレクタ(自動メモリ管理)は、一般に、これを時間内に一緒に割り当てることによってこれを提供します。シンプルなリニアアロケータは同じことをすることができます。また、小さなヒープのものを回避するために削除されたものを回避することもできます。 –

+0

さらに詳しい例はこのページを参照してください。http://www.cprogramming.com/tutorial/operator_new.html私は、デフォルトのアロケータをオーバーライドすることが可能であると確信しています。これにより、 'new int'オペレーションをオーバーライドします。 –

1

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

1

あなたが削除する前にこれを行うと:

x = NULL; 

それはメモリがをリークしています。あなたは何の役にも立たない記憶を失い、あなたがそのアドレスを失ったために自由になることはできません。 (nullポインタを削除することはできますが、何もしません)

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

削除した後も全く同じ新しいアドレスを取得する予定はありません。それは時々、ランダムに起こるかもしれませんが。

1

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

2)しないでください。あなたは参照を失っており、NULLポインタにdelete演算子を適用すると、何もしません。したがって、他の変数に参照を格納しないと、リソースリークが発生する可能性があります。新しいものをもう一度呼び出すと、最初にnew()で与えられた領域を解放していないと仮定してどこか他の場所に割り当てることになります

10

同じブロックをもう一度取得しますが、 。

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

2

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

コンパイラのバージョンでこれをテストするのは簡単です。

ただし、この動作の結果に依存しないように注意する必要があります。これは、任意の時刻/任意のOS /コンパイラへのアップグレードであっても変更できます。

私の考えていることは、プログラム内に同じ時間に割り当てられている他のスレッドがないかぎり、同じアドレスが得られる可能性が高いことです。しかし、コンパイラの特定のmalloc実装が異なるスレッドのために異なるスレッドを使うことを決めた場合(perfの方が良い)、同じアドレスを取得するかもしれません。

関連する問題