boost serialization problem with reference members

A

Abhishek Padmanabh

I have been trying out boost's serialization library for the past few
days. And I have come across a problem serializing a class that has a
reference member. The code is posted as below:

Code:
#include <iostream>
#include <fstream>
#include <string>

#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>

//for name value pairs when doing XML archiving
#include <boost/serialization/nvp.hpp>

class MyClassWithNoDefaultConstructor;
std::ostream& operator<<(std::ostream& os, const
MyClassWithNoDefaultConstructor& object);

//global integer variable... whose reference will be a member of
MyClassWithNoDefaultConstructor
int global_int = 10;

class MyClassWithNoDefaultConstructor
{
	public:
		MyClassWithNoDefaultConstructor(int i, int& ref_)
			: intMember(i), ref(ref_)
		{}
	private:
		int intMember;
		int& ref;
		template<class Archive>
		void serialize(Archive& ar, const unsigned int version)
		{
			ar & BOOST_SERIALIZATION_NVP(intMember);
			ar & BOOST_SERIALIZATION_NVP(ref);
		}
	friend class boost::serialization::access;
	friend std::ostream& operator<<(std::ostream& os, const
MyClassWithNoDefaultConstructor& object);
};

std::ostream& operator<<(std::ostream& os, const
MyClassWithNoDefaultConstructor& object)
{
	os << "\nMyClassWithNoDefaultConstructor contents:\n";
	os << "intMember - " << object.intMember << "\n";
	os << "ref - " << object.ref << "\n";
	return os;
}

namespace boost
{
	namespace serialization
	{
		template<class Archive>
		inline void save_construct_data(Archive & ar, const
MyClassWithNoDefaultConstructor* t, const unsigned int file_version)
		{
			// save data required to construct instance
			ar << t->intMember;
			ar << &(t->ref);
		}

		template<class Archive>
		inline void load_construct_data(Archive & ar,
MyClassWithNoDefaultConstructor* t, const unsigned int file_version)
		{
			// retrieve data from archive required to construct new instance
			int m;
			//int * ptr;
			int * ptr = new int();
			ar >> m;
			ar >> ptr;
			::new(t)MyClassWithNoDefaultConstructor(m, *ptr);
		}
	}
}

void SerializeMyClassWithNoDefaultConstructor(const std::string&
filename)
{
    MyClassWithNoDefaultConstructor object(111, global_int);
    std::ofstream ofs(filename.c_str());
    assert(ofs.good());
    boost::archive::xml_oarchive xml_oa(ofs);
    xml_oa << BOOST_SERIALIZATION_NVP(object);
}

void DeserializeMyClassWithNoDefaultConstructor(const std::string&
filename)
{
	char * buffer = new char[sizeof(MyClassWithNoDefaultConstructor)];
	MyClassWithNoDefaultConstructor* ptr =
reinterpret_cast<MyClassWithNoDefaultConstructor*>(buffer);
	std::ifstream ifs(filename.c_str());
	assert(ifs.good());
	std::cout << "inside deserialize()" << std::endl;
	boost::archive::xml_iarchive xml_ia(ifs);
	std::cout << "xml_iarchive constructed" << std::endl;
	xml_ia >> BOOST_SERIALIZATION_NVP(*ptr);
	std::cout << "deserialized" << std::endl;
	std::cout << *ptr;
	ptr->~MyClassWithNoDefaultConstructor();
	delete[] buffer;
	buffer=NULL;   ptr=NULL;
}

int main()
{
	const std::string filenameMyClassWithNoDefaultConstructor="/tmp/
testfileMyClassWithNoDefaultConstructor.xml";
	try
	{
	
SerializeMyClassWithNoDefaultConstructor(filenameMyClassWithNoDefaultConstructor);
	
DeserializeMyClassWithNoDefaultConstructor(filenameMyClassWithNoDefaultConstructor);
	}
	catch(const boost::archive::archive_exception& ex)
	{
		std::cout << ex.what() << "\n";
	}
	catch(const std::exception& ex)
	{
		std::cout << ex.what() << "\n";
	}
	return 0;
}

It compiles fine with g++ 3.4.6. But fails with a segmentation fault.
I tried fiddling around with it but the best I can do is cause it to
fail with a bus error or a stream error. Here is the documentation
that I am referring to - http://www.boost.org/libs/serialization/doc/index.html.
For reference members, the specific documentation page is -
http://www.boost.org/libs/serializa...html#references

The code works (or atleast it seems to) if you remove the reference
member. That is, I have it working for classes that don't have a
default constructor but what if there are constant or reference
members? The documentation seems to suggest it is possible to handle
them as are non-default constructor classes are, but I am not able to
get it to work.

Am I doing something silly there? Or is there a major gap between my
understanding and what the documentation says? I am using boost 1.32 -
can that be a reason? Can anyone help with the problem?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,704
Messages
2,569,334
Members
44,615
Latest member
neveseexick

Latest Threads

Top