0

私はセーフC ++を読んでおり、著者は以下のように循環参照について言及しています。

相互へのポインターを含む 2 つのオブジェクトを考えてみましょう

class A;

class B { public: A* a; };

class A { public: B* b; };

この状況は「循環参照」として知られています。A と B へのポインタは存在しますが、別の場所からこれらのオブジェクトの少なくとも 1 つへの他のポインタがない場合、いずれかの変数のメモリを再利用する方法がないため、メモリ リークが発生します。これらの 2 つのオブジェクトは、その後も幸せに暮らし、破壊されることはありません。

私の質問

  1. なぜメモリリークが発生するのですか? 対応するクラスのデストラクタでメモリを削除するのはなぜ悪い考えですか?
  2. 2つの物体が永遠に生き続けると著者が述べた根拠は何ですか?

お時間をいただきありがとうございます。

4

2 に答える 2

0

問題の概念は到達可能性です。基本的に、ポインタの基本セット(アクティブ変数など)から始めて、直接または間接的に問題のオブジェクトに到達できますか。そうでない場合、オブジェクトに到達できません。

到達不能オブジェクトの簡単な例は、ポインタがないオブジェクトです。循環参照の例は別の例です。問題のオブジェクトの両方へのポインターがありますが、オブジェクトにはまだ到達できません。

ほとんどの言語では、オブジェクトに到達できない場合、遅かれ早かれガベージコレクションされます。C ++では、動的に割り当てられたオブジェクトが到達不能になる前に、明示的に削除する必要があります。そうしないと、削除できません(そしてメモリがリークしました)。ガベージコレクションをシミュレートするための頻繁なC++手法の1つは、参照カウントポインタです。この手法は(他のガベージコレクション手法とは異なり)循環参照を正しく処理しないため、メモリリークが発生します。

C ++はガベージコレクションの恩恵を受けますが、これはC++では他のほとんどの言語ほど問題ではないことを理解することが重要です。C ++では、動的に割り当てられたオブジェクトは通常、存続期間が定義され、一部の外部イベントに応答して明示的に破棄されるオブジェクトにのみ対応します(または、プログラムが終了するとプログラムが終了するため、破棄されることはありません。期間-コンパイラの解析ツリーについて考えてみてください)。C ++は値のセマンティクスをサポートしているため、他のほとんどのオブジェクトはサポートされていません 動的に割り当てられますが、ローカル変数、またはより大きなオブジェクトのデータメンバーであり、その存続期間は自動的に管理されます。C ++には、メモリの削除を自動的に管理するための「スマート」ポインタがいくつかありますが、それらを広範囲に使用することに夢中になっている場合は、動的割り当てを悪用している可能性があります。

于 2013-03-14T09:08:34.867 に答える