問題タブ [smart-pointers]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - スマート ポインターが原因のメモリ リークを見つける
スマートポインタによって引き起こされるメモリリークを発見する「テクニック」を知っている人はいますか? 私は現在、C++で書かれた大規模なプロジェクトに取り組んでおり、参照カウントを伴うスマート ポインターを多用しています。明らかに、コードのどこかでまだ参照されているスマート ポインターによって引き起こされるメモリ リークがいくつかあるため、それらのメモリは解放されません。「不必要な」参照を含むコード行を見つけるのは非常に困難です。これにより、対応するオブジェクトが解放されなくなります (ただし、それはもはや役に立ちません)。
Web で、参照カウンターのインクリメント/デクリメント操作のコール スタックを収集することを提案するアドバイスを見つけました。これにより、どのコードが参照カウンターの増加または減少を引き起こしたのか、良いヒントが得られます。
しかし、私が必要としているのは、対応する「呼び出しスタックの増加/減少」をグループ化するある種のアルゴリズムです。これらのコール スタックのペアを削除した後、(少なくとも) 1 つの「コール スタックの増加」が残っていることを願っています。これで、リークを修正することは大したことではなくなります。
しかし、グループ化を行う「アルゴリズム」のアイデアはありますか?
開発はWindows XPで行われます。
(私が説明しようとしたことを誰かが理解してくれることを願っています...)
編集: 循環参照によるリークについて話しています。
c++ - スマート ポインター: オブジェクトの所有者は?
C++ はメモリの所有権、つまり所有権のセマンティクスがすべてです。
そのメモリを解放するのは、動的に割り当てられたメモリのチャンクの所有者の責任です。したがって、問題は本当に誰がメモリを所有するかになります。
C++ では、所有権は生のポインターが内部でラップされる型によって文書化されているため、優れた (IMO) C++ プログラムでは、生のポインターが渡されるのを見ることは非常にまれです (まれではありません)。誰がメモリを所有しているのかわからないため、ドキュメントを注意深く読まなければ、誰が所有権を持っているのかわかりません)。
逆に、生のポインターがクラスに格納されることはほとんどありません。各生のポインターは、独自のスマート ポインター ラッパー内に格納されます。(注:オブジェクトを所有していない場合は、オブジェクトを保存するべきではありません。オブジェクトがいつスコープから外れて破棄されるかがわからないためです。)
だから質問:
- 人々が遭遇した所有権のセマンティックのタイプは何ですか?
- これらのセマンティクスを実装するために使用される標準クラスは何ですか?
- どのような状況でそれらが役立つと思いますか?
回答ごとに 1 種類のセマンティック オーナーシップを保持して、個別に投票できるようにします。
概要:
概念的には、スマート ポインターは単純であり、単純な実装は簡単です。私は多くの試みられた実装を見てきましたが、それらは常に何らかの方法で壊れており、カジュアルな使用や例では明らかではありません. したがって、独自のスマート ポインターを展開するのではなく、ライブラリから十分にテストされたスマート ポインターを常に使用することをお勧めします。std::auto_ptr
または、Boost スマート ポインターの 1 つが私のニーズをすべてカバーしているようです。
std::auto_ptr<T>
:
1 人の人物がオブジェクトを所有しています。所有権の譲渡は許可されています。
使用法: これにより、所有権の明示的な譲渡を示すインターフェイスを定義できます。
boost::scoped_ptr<T>
1 人の人物がオブジェクトを所有しています。所有権の譲渡は許可されていません。
使用法: 明示的な所有権を示すために使用されます。オブジェクトは、デストラクタによって、または明示的にリセットされたときに破棄されます。
boost::shared_ptr<T>
( std::tr1::shared_ptr<T>
)
複数所有。これは単純な参照カウント ポインターです。参照カウントがゼロになると、オブジェクトは破棄されます。
使用法: オブジェクトが、コンパイル時に決定できない有効期間を持つ複数の権限を持つことができる場合。
boost::weak_ptr<T>
:
shared_ptr<T>
ポインターのサイクルが発生する可能性がある状況で使用されます。
使用法: サイクルのみが共有参照カウントを維持している場合に、サイクルがオブジェクトを保持するのを停止するために使用されます。
c++ - スマート ポインターとは何ですか? また、いつ使用する必要がありますか?
スマート ポインターとは何ですか? また、いつ使用する必要がありますか?
c++ - ブースト shared_ptr コンテナーの質問
マルチスレッド アプリケーションで使用されるポインターのコンテナー (std::vector) があるとします。コンテナーに新しいポインターを追加するとき、コードはクリティカル セクション (boost::mutex) を使用して保護されます。すべて順調です。コードは、処理のためにこれらのポインターの 1 つをスレッドに返すことができるはずですが、別の別のスレッドが、まだ使用されている可能性があるこれらのポインターの 1 つを削除することを選択する可能性があります。例えば:
そのため、thread1 が使用している間に、thread2 がポインターを削除する可能性があります。汚い。
代わりに、Boost 共有 ptr のコンテナーを使用したいと考えています。IIRC これらのポインターは参照カウントされるため、未加工のポインターではなく共有ポインターを返す限り、コンテナーからポインターを削除しても、最後の使用が範囲外になるまで実際には解放されません。すなわち
上記の例で、thread2 が erase を呼び出す前に thread1 がポインターを取得した場合、指しているオブジェクトは引き続き有効でしょうか? thread1 が完了しても実際には削除されませんか? グローバル ベクトルへのアクセスは、クリティカル セクションを介して行われることに注意してください。
これが shared_ptrs の仕組みだと思いますが、確認する必要があります。
c++ - ポインターとコンテナー
RAW ポインターをスマート ポインターの形式でラップして、例外セーフ メモリ管理を実現する必要があることは誰もが知っています。しかし、ポインターのコンテナーになると、問題はさらに厄介になります。
std コンテナーは、含まれているオブジェクトがコピー可能であることを主張するため、これにより std::auto_ptr の使用が除外されますが、boost::shared_ptr などは引き続き使用できます。
ただし、ポインターを安全に保持するように明示的に設計されたブースト コンテナーもいくつかあります。ポインター コンテナー ライブラリ
を参照してください。
問題は、smart_pointers のコンテナーよりも ptr_containers を使用した方がよい条件は何ですか?
c++ - boost::shared_ptr 標準コンテナ
クラス foo があり、std::map を使用して boost::shared_ptrs を保存したいとします。
新しい foo_sp をマップに追加したが、使用したキーが既に存在する場合、既存のエントリは削除されますか? 例えば:
元のポインター (p) は、p2 に置き換えられたときに解放されますか? そうなると確信していますが、質問/共有する価値があると思いました.
c++-cli - マネージ C++/CLI クラスの auto_ptr または shared_ptr に相当するもの
C++/CLI では、マネージド クラスでネイティブ クラスのメンバーを保持することは許可されていないため、マネージド クラスでネイティブ型を使用できます。その場合はポインターを使用する必要があります。
例を次に示します。
C++/CLI の世界で shared_ptr に相当するものを知っている人はいますか?
編集:「1800-Information」という提案をありがとう。あなたの提案に従って、STL.Net について確認しましたが、Visual Studio 2008 でのみ利用可能で、コンテナー + アルゴリズムを提供しますが、スマート ポインターは提供しません。
c++ - スマート ポインターへの参照を使用してはならないのはなぜですか?
スマート ポインターへの参照を使用するとメモリが破損する可能性があることをどこかで読んだことを思い出します。これは単に、スマート ポインターが破棄された後にその参照を使用したためですか? それとも、参照カウントがおかしくなっていますか?
明確にしてくれてありがとう
c++ - スマート ポインターで共変の戻り値の型を使用するにはどうすればよいですか?
次のようなコードがあります。
このコードはコンパイルされません。
ビジュアルスタジオで上げる
C2555: 仮想関数の戻り値の型のオーバーライドが異なり、共変ではありません
生のポインターを使用せずにboost::shared_ptr
返すと、コードがコンパイルされます (これは、C++ の共変の戻り値の型によるものだと理解しています)。問題は、 が から派生していないためであるboost::shared_ptr
ことがわかります。しかし、他のクラスで使用するために を返したいのですが、そうでない場合は、戻り値を戻り値の後にキャストする必要があります。 Ret1
boost::shared_ptr
RetInterface
boost::shared_ptr
Ret1
- 私は何か間違ったことをしていますか?
- そうでない場合、言語がこのようなものになっているのはなぜですか。このシナリオでは、スマート ポインター間の変換を処理するために拡張可能である必要があります。望ましい回避策はありますか?
c++ - std::auto_ptr を慣用的に使用するか、shared_ptr のみを使用しますか?
これshared_ptr
が tr1 にありますstd::auto_ptr
。両方とも異なるユース ケースがありますが、 のすべてのユース ケースはauto_ptr
でも解決できますshared_ptr
。auto_ptr
特定の時点で 1 つのクラスのみが所有権を持っていることを明示的に表現したい場合に、それを放棄するか、それとも使用し続けますか?
私auto_ptr
の見解では、コードの設計のニュアンスと指示を正確に追加することで、コードを明確にすることができますが、一方で、新しいプログラマーをトレーニングするときにさらに別の微妙な問題が追加されます。彼らはスマートポインターを理解する必要があり、それらがどのように機能するかの詳細。どこでもスマート ポインターを 1 つだけ使用する場合は、「すべてのポインターを にラップする」というルールを設定するだけで済みますshared_ptr
。
これについてどう思いますか?