boost serialization problem with reference members

Discussion in 'C++' started by Abhishek Padmanabh, Feb 21, 2007.

  1. 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?
    Abhishek Padmanabh, Feb 21, 2007
    #1
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    8
    Views:
    2,234
    deadsea
    Jan 2, 2005
  2. Replies:
    3
    Views:
    1,023
  3. Dimitri Ognibene
    Replies:
    4
    Views:
    776
    Dimitri Ognibene
    Sep 2, 2006
  4. Abhishek Padmanabh
    Replies:
    0
    Views:
    262
    Abhishek Padmanabh
    Feb 21, 2007
  5. Replies:
    2
    Views:
    951
Loading...

Share This Page