言い換えれば、実装はどのようにカウントを追跡しますか?
キーがポインタのアドレスで値が参照の数であるすべてのshared_ptr
インスタンスからアクセスできるマップのようなオブジェクトが維持されていますか? shared_ptr
を実装する必要がある場合、これが私の頭に浮かぶ最初のアイデアです。
これらの参照カウントスマートポインタの場合、メモリリークの可能性はありますか?もしそうなら、どうすればそれらを回避できますか?
これに対する2つの異なる非侵入型アプローチを見てきました。
here に移動して一番下までスクロールすると、これらの方法をより明確に説明する優れた図があります。
参照カウントスマートポインタを使用してメモリリークを作成するのは非常に簡単です。グラフに周期があるオブジェクトのグラフのような構造を作成するだけです。サイクル内のオブジェクトは、お互いが解放されるのを防ぎます。これは自動的に解決することはできません。たとえば、二重リンクリストを作成するときは、一度に複数のオブジェクトを削除しないように注意する必要があります。
各スマートポインタオブジェクトには、共有参照カウントが含まれています(rawポインタごとに1つ)。
this の記事をご覧ください。この実装は、これらをコピーされる別のオブジェクトに格納します。また、 ブーストのドキュメント を確認するか、スマートポインタの ウィキペディアの記事 を確認することもできます。
多くの回答は、参照カウントの保存方法(同じネイティブポインターを保持するすべてのshared_ptrの共有メモリに保存される)に対応していますが、ほとんどの場合、リークの問題は回避されます。
参照カウントポインタを使用してメモリリークを行う最も簡単な方法は、サイクルを作成することです。例として、すべてのポインターが少なくとも2つの要素を持つshared_ptrである二重リンクリストは、削除されないことが保証されています。外部ポインターが解放されても、内部ポインターはカウントされ、参照カウントは0に到達しません。つまり、少なくとも、最も単純な実装ではそうです。
サイクルの問題に対する最も簡単な解決策は、shared_ptr(参照カウントポインター)を、オブジェクトの所有権を共有しない弱いポインターと混合することです。
共有ポインターは、リソース(ポインター)と追加のreference_count情報の両方を共有します。弱ポインターを使用すると、参照カウントが2倍になります。共有ポインター参照カウントと弱ポインター参照カウントがあります。共有ポインター数が0に達するとリソースは解放されますが、reference_count情報は、最後の弱いポインターが解放されるまで存続します。
二重リンクリストでは、外部参照はshared_ptrに保持されますが、内部リンクは単にweak_ptrです。外部参照(shared_ptr)がない場合は常に、リストの要素が解放され、弱参照が削除されます。最後に、すべての弱参照が削除され、各リソースへの最後の弱ポインターがreference_count情報を解放します。
上記のテキストよりも混乱は少ないです...後でもう一度やり直します。
いいえ。shared_ptrは、参照カウント用に1つの追加ポインターを保持するだけです。
Shared_ptrオブジェクトのコピーを作成すると、参照数を含むポインターがコピーされ、それが増加し、含まれているオブジェクトにポインターがコピーされます。
私が覚えている限り、Effective C++の章で扱われている参照カウントポインタの問題がありました。
原則として、参照をインクリメント/デクリメントしてポインタオブジェクトを破棄することを知っている参照を保持するクラスへのポインタを含む「ライト」ポインタクラスがあります。その参照カウントクラスは、参照されるオブジェクトを指します。