Boost logo

Boost Users :

From: Youhei Murakami (ym555_at_[hidden])
Date: 2007-11-29 17:02:34


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;
}




Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net