1

私は次の状況にあります:

Foo1 foo1* = new Foo1(...);
Foo2 foo2* = new Foo2(foo1, ...);

また

Foo1 foo1(...);
Foo2 foo2(foo1, ...);

Foo1とFoo2を削除する必要があります。正しく理解できれば、割り当てられた順序とは逆の順序でメモリを解放する必要があります。だから私はすべきです:

delete(foo2);
delete(foo1);

ただし、foo2のデストラクタでfoo1がNULLに設定されているため、これを行うことはできません。したがって、foo2を削除しようとすると、NULL参照を削除しようとして、アサートがトリガーされます。これを回避する方法はありますか?ここでの最善の解決策は、メモリをスタックに割り当てることを可能にするでしょうが、それは絶対に必要ではありません。


編集:

このスレッドを参照してください:shared_ptrは自動的にメモリを解放しますか?

ご回答ありがとうございます。私は問題が何であるかについて(明らかに)間違っていました。APIを変更できないため、ここでshared_ptrを使用する必要があります。

Foo1 *foo1 = new Foo1(...);
shared_ptr<Foo2> foo2(foo1);

ここでshared_ptrは、foo1によって使用されるメモリの解放を処理しますか?私が正しく理解していれば、foo1でdeleteを呼び出す必要はありませんか?

別の質問として質問し、それにリンクします。

4

2 に答える 2

7

deleteまず、を使用して作成されたオブジェクトのみが必要ですnew。一般的に、によって作成されたオブジェクトには順序の依存関係はありませんnew。ただし、foo2がfoo2のデストラクタのfoo1で関数を呼び出す場合など、コンストラクタ/デストラクタの依存関係が存在する可能性があります。この場合、破壊の順序が重要です。

次に、foo2のfoo1ポインターがnullに設定されている場合でも、それはfoo2に保持されているポインターのローカルコピーにすぎません。ポインタの他のコピーには影響しません。foo2でfoo1をnullに設定することは、オブジェクトを使用しないように通知するため、悪い考えではありませんが、これは、デストラクタを呼び出したり、オブジェクトを呼び出したりfreeすることとは異なります。

于 2012-10-02T23:21:50.633 に答える
5

割り当てられたのとは逆の順序でメモリを解放する必要があります。

newええと、パワーとのような汎用アロケータではありませんdelete

ただし、foo2のデストラクタでfoo1がNULLに設定されているため、これを行うことはできません。

これはWTFの巨大な山です。いったいなぜあなたはそのような計画を持っているのでしょうか?deleteそして、あなたがしなかったオブジェクトを作成することさえ考えないでくださいnew

正気の人のようにスマートポインタを使用して、これらすべてを忘れてください。

于 2012-10-02T23:21:28.287 に答える