2017-03-11 16 views
0

私は次のコードでバイナリツリーを実装しようとしていますを使用してサイズ8の不正な書き込みをスロー:Valgrindのは、スマートポインタ

==18345== Invalid write of size 8 
==18345== at 0x400F26: Node::addLeft(int) (Ex9.2.cpp:264) 
==18345== by 0x401182: main (Ex9.2.cpp:360) 
==18345== Address 0x5ab61f8 is 40 bytes inside a block of size 48 free'd 
==18345== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==18345== by 0x402603: __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2> >::deallocate(std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2>*, unsigned long) (new_allocator.h:110) 
==18345== by 0x4023DC: std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2> > >::deallocate(std::allocator<std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2> >&, std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2>*, unsigned long) (alloc_traits.h:517) 
==18345== by 0x40211D: std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2> > >::~__allocated_ptr() (allocated_ptr.h:72) 
==18345== by 0x402885: std::_Sp_counted_ptr_inplace<Node, std::allocator<Node>, (__gnu_cxx::_Lock_policy)2>::_M_destroy() (shared_ptr_base.h:539) 
==18345== by 0x401649: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:167) 
==18345== by 0x40135C: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:659) 
==18345== by 0x401315: std::__shared_ptr<Node, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:925) 
==18345== by 0x401331: std::shared_ptr<Node>::~shared_ptr() (shared_ptr.h:93) 
==18345== by 0x400F19: Node::addLeft(int) (Ex9.2.cpp:262) 
==18345== by 0x401182: main (Ex9.2.cpp:360) 
:valgrindのを実行しているとき、私は次のレポートを持っている

Node* Node::addLeft(int v){ 
    left = make_shared<Node> (v).get(); 
    //cout<<"set left "<<left->value<<endl; 
    left->parent=this; 
    return this; 
} 

あなたはこのエラーについて考えていますか? ご協力いただければ幸いです!

+2

一時的に 'shared_ptr'を作成して、元の生ポインタを抽出して保存します。セミコロンでは、一時的なものが破棄され、新しく作成されたノードが削除され、 'left'がダングリングします。そうすれば、あなたのプログラムは、この今のダングリングしているポインタを逆参照し、未定義の動作を示します。 –

+0

優秀!ご説明いただきありがとうございます。左のメンバをNode *からshared_ptr に変更しました。私は今一時的にセミコロンで破壊されているが、所有権が左のメンバーに転送されているので、新しく作成されたNodeオブジェクトは破壊されないと思います。私が間違っていれば私を修正してください。 – PerelMan

答えて

0

。私は、左のメンバーをNode *からshared_ptrに変更しました。私は今一時的にセミコロンで破壊されているが、所有権が左のメンバーに転送されているので、新しく作成されたNodeオブジェクトは破壊されないと思います。

+1

あなたはこれを削除してイゴールに答えを書いてください。そうでない場合は、彼の提案を使って自分の答えを書くことができます。しかし、それが立てば、これは答えではありません。 –