26

スマート ポインターへの参照を使用するとメモリが破損する可能性があることをどこかで読んだことを思い出します。これは単に、スマート ポインターが破棄された後にその参照を使用したためですか? それとも、参照カウントがおかしくなっていますか?

明確にしてくれてありがとう

4

6 に答える 6

15

ここでshared_ptrについて話していると仮定します...

これは単に、スマートポインターが破棄された後、その参照を使用したためですか?

これは良い答えです。参照が参照しているポインタの存続期間も完全にはわからない場合があります。

これを回避するには、boost::weak_ptrを調べます。参照カウントには参加しません。あなたがそれを使う必要があるとき、それはあなたがそれを使い終えると消えるshared_ptrをあなたに与えます。また、参照されたポインタが収集されたときに通知されます。

weak_ptrのドキュメントから

weak_ptrクラステンプレートは、shared_ptrによってすでに管理されているオブジェクトへの「弱参照」を格納します。オブジェクトにアクセスするには、shared_ptrコンストラクターまたはメンバー関数lockを使用してweak_ptrをshared_ptrに変換できます。オブジェクトへの最後のshared_ptrがなくなり、オブジェクトが削除されると、削除されたオブジェクトを参照するweak_ptrインスタンスからshared_ptrを取得しようとして失敗します。コンストラクターは、boost::bad_weak_ptr型とweak_ptr型の例外をスローします。 :lockは空のshared_ptrを返します。

メソッドexpired()は、ptrがまだ存在するかどうかも通知することに注意してください。

于 2008-10-07T15:44:32.507 に答える
6

スマート ポインター (または任意の割り当て管理オブジェクト) を使用する場合、refs/derefs/locks/unlocks を管理するために、コンストラクター/デストラクターで定義された動作を当てにしています。その結果、これらのタイプのオブジェクトが適切に機能するには、真のオブジェクトである必要があります。そのようなオブジェクト (またはポインター) への参照を使用する場合、メカニズムをバイパスしています (そして、くさびを求めています)。

于 2008-10-07T16:08:57.230 に答える
4

スマート ポインターへの参照が適切な場合は、まだ多くあります。明らかな例は、別のスマート ポインターへの参照をパラメーターとして受け入れるスマート ポインター クラス自体の代入メソッドです。

スマート ポインター参照を受け入れるメソッドを作成するということは、パラメーターがスマート ポインターの内部参照カウントをインクリメントしないことを意味します。これによりパフォーマンスが向上しますが、おそらくそれほど多くはありません。また、メソッドが参照 (または元のスマート ポインター) を使用して実行できないことがたくさんあります。これらが何であるかを知っていて、それらを避ければ、参照渡しは問題なく機能します。もちろん、スマート ポインターの目的は、これらのことを知る必要がないようにすることです。

また、スマート ポインター パラメーターの値を変更するメソッドがある場合は、他の型と同様に、参照として渡す必要があります。

于 2008-10-07T16:48:29.133 に答える
1

スマート ポインターの "スマート" 部分は、スマート ポインター クラスのコンストラクター、デストラクター、代入演算子、およびその他の関数によって管理されます。参照を使用すると、これらの操作を回避できます。参照が初期化されたときにコンストラクターが呼び出されず、参照がスコープ外になったときにデストラクタが呼び出されません。

本質的に、スマート ポインターへの参照はダム ポインターであり、後者に伴うすべてのリスクと落とし穴があります。

于 2008-10-07T16:49:27.353 に答える
0

カスタムメイドのスマートポインターがあり、常に「const refsomething &」を渡す習慣があります。

スマート ポインターをインクリメントまたはデクリメントすることはありません。したがって、さらに重要なことに、InterLockedIncrement/Decrement の呼び出しが回避され、メモリ フェンスとそれに伴うすべてのこと (バスのロック、キャッシュの無効化など) が回避されます。 .

于 2008-10-07T18:14:32.873 に答える
0

スマート ポインターへの参照を関数に渡すことは完全に安全であり、良い考えです。オブジェクトは消えるかもしれませんが、スマート ポインターは消えません。少なくとも関数が戻るまでは、null と言ってそこに座ったままになります。これは、スコープ内でスマート ポインターにエイリアスを設定する最良の方法です。参照先に const 修飾子を付けて参照を使用すると、インテリジェントな監視参照が得られます。

const smart_ptr<T>&

興味深いことに、便利なことに、const を使用すると、参照を使用してスマート ポインターを null にしてオブジェクトを削除することはできなくなりますが、元のスマート ポインター自体が null になるのを止めることはできず、参照にはその変更が反映されます。

関数からスマート ポインターへの参照を返すことは、あらゆる種類の問題を引き起こします。

于 2013-10-01T14:10:50.093 に答える