2012-05-09 8 views
2

私はオブジェクトへの共有のポインタを返す関数(あるため、多くの大規模な依存関係のMyObjectに定義を含めることは困難である)している:C++:エラーからコピーするとき*のstd :: shared_ptrの

std::shared_ptr<MyObject> f(std::string params) 
{ 
    return std::shared_ptr<MyObject>(new MyObject(params)); 
} 

ケース1:このコードCRAながらvalgrind -v --tool=memcheck

std::shared_ptr<MyObject> obj_ptr = f("hello"); 
MyObject obj = *obj_ptr; 

でエラーなしに、このコードが動作する理由を誰もが知っていますシーズ:

ケース2:クラッシュとはvalgrind -v --tool=memcheck

MyObject obj = *f("hello"); 

MyObjectにクラスが作業代入演算子を持っており、(両方がケース1で検証)コンストラクタをコピーして、いくつかのエラーが発生します。

std::shared_ptr<MyObject>f経由)の作成、ポインタへのコピー、スタック上のオブジェクトへのポインタのコピー、およびポインタの削除を試みました。スタック上の最終的なオブジェクトは、罰金はまだです:

ケース3:valgrind -v --tool=memcheck

std::shared_ptr<MyObject> obj_ptr = f("hello"); 
MyObject * obj_ptr2 = new MyObject(*obj_ptr); 
MyObject obj3 = *obj_ptr2; 
delete obj_ptr2; 
obj3.print(); 

とエラーがstd::shared_ptrが右辺値として作成されるかもしれないので、エラーではありませんし、できるだけ早くそのメモリを解放します*演算子は実行されますか?

+0

何コンパイラのどのバージョンを使用していますか? – ildjarn

+0

クラッシュしたときのエラーは何ですか?スタックトレースが役立つかもしれません... –

+1

MyObjectコピーコンストラクタはディープコピーをしていますか? (ケース1は、浅いコピーでは正常に動作します)。 – bobah

答えて

8

MyObjectのメンバーの1つをコピーコンストラクタに浅くコピーしているという問題があります。次に、有効ではなくなった浅いデータにアクセスしようとするか、またはそれを2回削除します。

ケースを検討してください: 最初と3番目のケースでは、スタックオブジェクトを操作すると、すべてのコピーが作成される最初のオブジェクトがまだ有効です。 2番目のケースでは、shared_ptrはコピー構築後に消えて、デストラクタMyObjectを呼び出します。

あなたは以下のようなものを第三のケースを変更した場合、私はそれがクラッシュしました疑い:

MyObject * obj_ptr2 = new MyObject("hello"); 
MyObject obj3 = *obj_ptr2; 
delete obj_ptr2; 
obj3.print(); 
+0

+1私はあなたが正しいと思います - 私は実際にコール可能なデストラクタを持っています( 'clear()')。 ** Case 3 **をもう一度試しましたが、元のオブジェクトがコピーされた後に破壊され、エラーが発生しました。 – user

+0

それはどこかに浅いコピーをしていたことが判明しました。ありがとう。 – user

関連する問題