Hello everyone. I tried to compile a code that has written below and I had met runtime error. That error is the memory corruption. A memory corruption occurs when just before exit main function and causes are in binary-serialization, but I don't understand this fenomenon. If someone who knows the reason of this matter, please tell me. [environment] Windows XP 64bit Visual Studio 2005 sp1 boost-1_34_1 #define _SCL_SECURE_NO_WARNINGS #pragma warning(push) #pragma warning(disable: 4267) #pragma warning(disable: 4103) #include <stdio.h> #include <tchar.h> #define CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #include <iostream> #include <fstream> #include <cstdlib> #include <vector> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/serialization/serialization.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/weak_ptr.hpp> #include <boost/serialization/version.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/tracking.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/binary_object.hpp> #include <boost/serialization/split_member.hpp> #define BOOST_LIB_NAME boost_serialization #include <boost/config/auto_link.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost/serialization/export.hpp> #pragma warning(pop) using namespace std; using namespace boost; using namespace boost::serialization; using namespace boost::archive; namespace test { class nodebase : public enable_shared_from_this<nodebase> { // occurs memory corruption when serializing public: typedef shared_ptr<nodebase> NodePointer; typedef weak_ptr<nodebase> NodeWeakPointer; typedef vector<NodePointer> Children; typedef Children::iterator ChildIterator; typedef vector<NodeWeakPointer> Parents; typedef Parents::iterator ParentIterator; public: nodebase(); nodebase( const string &n ); nodebase( const string &n, const Children &c ); nodebase( const string &n, const Children &c, const Parents &p ); virtual ~nodebase(); private: struct Impl { Impl(); Impl( const string &n ); Impl( const string &n, const Children &v ); Impl( const string &n, const Children &v, const Parents &p ); public: string name; Children children; Parents parents; private: friend class serialization::access; template <class Archive> void serialize( Archive &ar, const unsigned int version ); }; shared_ptr<Impl> pimpl; private: // serialization friend class serialization::access; template <class Archive> void serialize( Archive &ar, const unsigned int version ); public: string getname( void ){ return pimpl->name; } void SetParent( const NodePointer &parent ); void SetParents( const Parents &parents ); NodePointer GetParent( const string &name ); Parents GetParents( void ); Children GetChildren( void ); void AddChild( const NodePointer &child ); void RemoveChild( const NodePointer &child ); void Traverse( void ); private: void Traverse( const NodePointer &root ); }; nodebase::Impl::Impl() { } nodebase::Impl::Impl( const string &n ) : name(n) { } nodebase::Impl::Impl( const string &n, const Children &c ) : name(n), children(c) { } nodebase::Impl::Impl( const string &n, const Children &c, const Parents &p ) : name(n), children(c), parents(p) { } template <class Archive> void nodebase::Impl::serialize( Archive &ar, const unsigned int version ) { ar & make_nvp( "name", make_binary_object( &name, sizeof(name) ) ); ar & make_nvp( "children", make_binary_object( &children, sizeof(children) ) ); ar & make_nvp( "parents", make_binary_object( &parents, sizeof(parents) ) ); } nodebase::nodebase() { } nodebase::nodebase( const string &n ) : pimpl( new Impl( n ) ) { } nodebase::nodebase( const string &n, const Children &c ) : pimpl( new Impl( n, c ) ) { } nodebase::nodebase( const string &n, const Children &c, const Parents &p ) : pimpl( new Impl( n, c, p ) ) { } nodebase::~nodebase() { } template <class Archive> void nodebase::serialize( Archive &ar, const unsigned int version ) { ar & make_nvp( "pimpl", make_binary_object( &pimpl, sizeof(pimpl) ) ); } template void nodebase::serialize<archive::binary_oarchive>( archive::binary_oarchive &ar, const unsigned int version ); template void nodebase::serialize<archive::binary_iarchive>( archive::binary_iarchive &ar, const unsigned int version ); void nodebase::SetParent( const nodebase::NodePointer &p ) { assert( pimpl->parents.size()+1 < 2 ); pimpl->parents.push_back( p ); } nodebase::NodePointer nodebase::GetParent( const string &name ) { for( ParentIterator i = pimpl->parents.begin(); i != pimpl->parents.end(); i++ ){ NodePointer tmp((*i)); if( tmp->getname() == name ) { return tmp; } } return NodePointer(); } nodebase::Parents nodebase::GetParents( void ) { return pimpl->parents; } nodebase::Children nodebase::GetChildren( void ) { return pimpl->children; } void nodebase::AddChild( const nodebase::NodePointer &child ) { child->SetParent( shared_from_this() ); //!!!!ERROR!!!! incur a memory leak this->pimpl->children.push_back( child ); } void nodebase::RemoveChild( const NodePointer &child ) { for( ChildIterator i = pimpl->children.begin(); i != pimpl->children.end(); i++ ){ if( (*i).get() == child.get() ){ pimpl->children.erase( i ); break; } } } void nodebase::Traverse( void ) { Children children = this->GetChildren(); for( ChildIterator i = children.begin(); i != children.end(); i++ ){ Traverse( *i ); } } void nodebase::Traverse( const NodePointer &node ) { if( !node ){ return; } Children children = node->GetChildren(); for( ChildIterator i = children.begin(); i != children.end(); i++ ) { Traverse( *i ); } } class simple_class { // not occur memory corruption when serializing friend class access; string name; template <class Archive> void serialize( Archive &ar, unsigned int ) { ar & name; } }; }; BOOST_CLASS_TRACKING(test::nodebase, boost::serialization::track_always); int _tmain(int argc, _TCHAR* argv[]) { using namespace test; { shared_ptr<nodebase> root( new nodebase(string("root")) ); shared_ptr<nodebase> c1( new nodebase(string("c1")) ); shared_ptr<nodebase> c2( new nodebase(string("c2")) ); shared_ptr<nodebase> c3( new nodebase(string("c3")) ); shared_ptr<nodebase> c4( new nodebase(string("c4")) ); shared_ptr<nodebase> c5( new nodebase(string("c5")) ); c3->AddChild( c5 ); c1->AddChild( c3 ); c2->AddChild( c4 ); root->AddChild( c1 ); root->AddChild( c2 ); root->Traverse(); { // output ofstream ofile( "serialized", ios::binary ); try { boost::archive::binary_oarchive oa( ofile ); oa << BOOST_SERIALIZATION_NVP(root); } catch( boost::archive::archive_exception &e ) { cout << "At the output : " << e.what() << endl; ofile.close(); getchar(); exit(1); } ofile.close(); } shared_ptr<nodebase> in; { // input ifstream ifile( "serialized", ios::binary ); try { boost::archive::binary_iarchive ia( ifile ); ia >> BOOST_SERIALIZATION_NVP(in); in->Traverse(); } catch( boost::archive::archive_exception &e ) { cout << "At the input : " << e.what() << endl; ifile.close(); getchar(); exit(e.code); } ifile.close(); } } getchar(); return 0; }