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 (Text):

    #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. Advertisements

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,357
    deadsea
    Jan 2, 2005
  2. Replies:
    3
    Views:
    1,132
  3. Dimitri Ognibene
    Replies:
    4
    Views:
    871
    Dimitri Ognibene
    Sep 2, 2006
  4. Abhishek Padmanabh
    Replies:
    0
    Views:
    291
    Abhishek Padmanabh
    Feb 21, 2007
  5. Replies:
    2
    Views:
    1,023
Loading...

Share This Page