5

タイトルの質問についてさらに説明が必要です。私のシナリオを説明しましょう。

ヒープ上のいくつかのオブジェクトへのポインターのリスト コンテナーがあります。新しいオブジェクトが作成されるたびに、それへのポインターがリストに追加され、オブジェクトが削除されるたびにそのポインターが削除されます。このリストのすべてのポインターは常に有効であると言っても過言ではありません。

リスト上のオブジェクトの多くには、同じリスト上の他のオブジェクトへのポインタが含まれています。

これらのポインターのいずれかを逆参照する前に、CheckAgainstList(ptr*)関数を使用して、あるオブジェクトが同じリストの別のオブジェクトを指しているため、削除されたオブジェクトを指していないことを確認したいと思います。

アルミ箔の帽子をかぶって、これは可能ですか?

  1. オブジェクト A には、メモリ アドレス のオブジェクト B へのポインタがあります 0x00988e50
  2. オブジェクト B が削除されます。
  3. オブジェクト C が作成され、新しく解放されたメモリ空間に配置されます0x00988e50
  4. CheckAgainstList(ptr*)オブジェクト C がリスト上にあり、B が占有していたのと同じメモリアドレスにあるため、ポインタをチェックすると true を返します。

A は B へのポインターを持っていると考えているため、バグが発生していますが、B はなくなり、いわば C が代わりになっています。

この潜在的なバグは可能ですか?

4

5 に答える 5

6

それが可能であるだけでなく、それは非常に可能性が高いです。優れたメモリアロケータは、断片化と肥大化を減らすために、できるだけ頻繁にメモリを再利用しようとします。

解決しようとしている問題は、weak_ptrの影響を受けやすい可能性があります。これは、使用する前に有効性を確認できます。

于 2012-06-22T18:04:02.640 に答える
4

オペレーティングシステムによっては、メモリアドレスは再利用されます。そうしないと、プログラムが多くの割り当てと割り当て解除を実行し、マシンにRAMがある場合よりも多く、続行できなくなります。

結局のところ、答えはオペレーティングシステムと、C++自体よりもメモリ管理スキームに関するものです。結局のところ、free-store(動的)メモリを割り当てるときに起こることは、プロセスが(標準ライブラリ関数を介して)特定のOSルーチンを呼び出して、要求された量のメモリを割り当て、割り当てられたメモリにアドレスを返すことです。

于 2012-06-22T18:02:35.507 に答える
4

はい、そのバグは完全に可能です。

基本的に、あなたがしていることはかなり危険であり、バグにすぐにつながります。ある種の参照カウントスマートptrを使用するのが最善かもしれません。C++11にはstd::shared_ptrが含まれています。これは、通常のポインターの代わりに使用できることを意味します。このようにして、すべてが終了するまでメモリが解放されず、説明したような問題が軽減されます。

他の唯一のオプションは、他のすべてのオブジェクトをスキャンして、削除された「B」を参照しているかどうかを確認し、現在削除されているポインターへのポインターを「null」のように実行することです。

于 2012-06-22T18:01:39.480 に答える
1

単一のタイプのオブジェクトのみを作成する場合、バグが発生する可能性が高くなります。しかし、それは常に完全に可能です。

于 2012-06-22T18:03:58.567 に答える
0

はい、それは起こり得ます。これを防ぐには、オブジェクトを削除するときに、リストを調べて、削除されたオブジェクトへのポインターをNULLを指すように設定します。

于 2012-06-22T18:04:48.503 に答える