
Hello everyone. I tried to serialize tree data structure. Tree-structure's "node"-class holds "Impl"-structure and Impl-structure holds child nodes as vector<shared_ptr<node> >. Problems occur when serializing a tree structure that was constructed using above structures. Compile errors not occur, but run-time error occures at serialization of input-stream. If exists someone who knows the reason of it., please teach me that. please god bless me! A problematic souce code has been written below and is attached on this mail. [Emveironment] -Windows XP 64bit -Visual Studio 2005 sp1 -boost-1_34_1 #include <iostream> #include <fstream> #include <cstdlib> #include <vector> #include <boost/shared_ptr.hpp> #include <boost/intrusive_ptr.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/version.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/tracking.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/serialization/nvp.hpp> #define BOOST_LIB_NAME boost_serialization #include <boost/config/auto_link.hpp> #include <boost/archive/text_woarchive.hpp> #include <boost/archive/text_wiarchive.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/split_member.hpp> using namespace std; using namespace boost; using namespace boost::serialization; namespace test { class nodebase { public: typedef shared_ptr<nodebase> NodePointer; typedef vector<NodePointer> Children; typedef Children::iterator ChildIterator; public: nodebase(){} nodebase( const wstring &n ) : name(n) {} virtual ~nodebase(){} wstring getname() { return name; } void setname( const wstring &newname ) { name = newname; } private: wstring name; private: friend class serialization::access; template <class Archive> void serialize( Archive &ar, const unsigned int version ) { ar.register_type<nodebase>(); ar & name; } public: virtual void SetParent( const NodePointer &parent ) = 0; virtual Children GetChildren( void ) = 0; virtual void AddChild( const NodePointer &child ) = 0; virtual void RemoveChild( const NodePointer &child ) = 0; virtual void Traverse( const NodePointer &root ) = 0; }; class node : public nodebase { private: struct Impl { Impl() {} Impl( const Children &v ) : children(v) {} Impl( const Children &v, const NodePointer &p ) : children(v), parent(p) {} public: Children children; NodePointer parent; private: friend class serialization::access; template <class Archive> void serialize( Archive &ar, const unsigned int version ) { ar.register_type<Impl>(); ar & children; //ar & parent; } }; shared_ptr<Impl> pimpl; public: // constructor/destructor node() : pimpl( new Impl ) {} node( const wstring &n ) : nodebase(n), pimpl( new Impl ) {} node( const Children &v ) : pimpl( new Impl( v ) ) {} node( const Children &v, const NodePointer &p ) : pimpl( new Impl( v, p ) ) {} private: // serialization friend class serialization::access; template <class Archive> void serialize( Archive &ar, const unsigned int version ) { base_object<nodebase>(*this); void_cast_register<node, nodebase>(); ar.register_type<node>(); ar & pimpl; } public: // operations virtual void SetParent( const NodePointer &p ) { pimpl->parent = p; } virtual Children GetChildren( void ) { return pimpl->children; } virtual void AddChild( const NodePointer &child ) { this->pimpl->children.push_back( child ); } virtual void RemoveChild( const shared_ptr<nodebase> &child ) { for( ChildIterator i = pimpl->children.begin(); i != pimpl->children.end(); i++ ) { if( (*i).get() == child.get() ) { pimpl->children.erase( i ); break; } } } virtual void Traverse( const shared_ptr<nodebase> &node ) { if( !node ) { return; } #ifdef _DEBUG wcout << node->getname() << endl; #endif Children children = node->GetChildren(); for( ChildIterator i = children.begin(); i != children.end(); i++ ) { Traverse( *i ); } } void print() { for( Children::iterator i = pimpl->children.begin(); i != pimpl->children.end(); i++ ) { wcout << i->get()->getname() << endl; } } }; }; BOOST_CLASS_TRACKING(test::nodebase, boost::serialization::track_always); BOOST_CLASS_TRACKING(test::node, boost::serialization::track_always); int _tmain(int argc, _TCHAR* argv[]) { using namespace test; { node::NodePointer root( new node(wstring(L"root")) ); node::NodePointer c1( new node(wstring(L"c1")) ); node::NodePointer c2( new node(wstring(L"c2")) ); node::NodePointer c3( new node(wstring(L"c3")) ); node::NodePointer c4( new node(wstring(L"c4")) ); node::NodePointer c5( new node(wstring(L"c5")) ); c3->AddChild( c5 ); c1->AddChild( c3 ); c2->AddChild( c4 ); root->AddChild( c1 ); root->AddChild( c2 ); root->Traverse( root ); { // output wofstream ofile( "serialized.txt" ); try { archive::text_woarchive oa( ofile ); oa << (const node&)(*root); } catch( boost::archive::archive_exception &e ) { cout << "At the output : " << e.what() << endl; getchar(); ofile.close(); exit(1); } ofile.close(); } node::NodePointer in; { // input wifstream ifile( "serialized.txt" ); try { archive::text_wiarchive ia( ifile ); ia >> in; } catch( boost::archive::archive_exception &e ) { cout << "At the input : " << e.what() << endl; getchar(); ifile.close(); exit(e.code); } ifile.close(); } } getchar(); return 0; }