1

Im having a bit of trouble trying to figure out why this piece of code would crash when the start the function returns 0;

I suspect that when it returns from the start function it calls the destructors for xml_iarchive and it is failing inside there.

do i have to call flush or some function to do a clean up before xml_iarchive calls its destructors.

I have no idea, :)

    // serialize
class FileLayout 
{

private:

    std::string m_name;
    int m_datetime;
    std::string m_version;

    std::string m_clientpath;
    int m_length;

public:

    FileLayout()
    {

    };

    FileLayout(std::string name ,int datetime, 
                std::string version, std::string clientpath, 
                int length)
    {
        m_name = name;
        m_datetime = datetime;
        m_version = version;
        m_clientpath = clientpath;
        m_length = length;
    };

    // Allow serialization to access non-public data members.
    friend class boost::serialization::access;

    template<typename Archive>
    void serialize(Archive& ar, const unsigned version) 
    {
        ar & boost::serialization::make_nvp("Name", m_name);
        ar & boost::serialization::make_nvp("DateTime", m_datetime);
        ar & boost::serialization::make_nvp("Version", m_version);
        ar & boost::serialization::make_nvp("ClientPath", m_clientpath);
        ar & boost::serialization::make_nvp("Length", m_length);
    }

    // get

    std::string name()
    {
        return m_name;
    };

    int datetime()
    {
        return m_datetime;
    };

    std::string version()
    {
        return m_version;
    };

    std::string clientpath()
    {
        return m_clientpath;
    };

    int length()
    {
        return m_length;
    };

};


    int Start(std::string &data) // xml 
    {
  // set filesize
  // set name
  boost::iostreams::basic_array_source<char> device(data.c_str(), data.size());
  boost::iostreams::stream<boost::iostreams::basic_array_source<char> > s(device);
  boost::archive::xml_iarchive ia(s,boost::archive::no_header);

  ia >> BOOST_SERIALIZATION_NVP(filelayout);

  data.clear();

  return 0; // fails here 
    }

2 Answers2

0

Turns out it was a problem with packing, I spent a whole day on this problem

0

Since I had a similar issue and was somewhat frustrated at the original answer to this I thought it worth adding my solution.

In my case my saving function had this code;

std::ofstream ofs(fileName.get(), std::ofstream::out);
if (ofs.is_open())
{
    boost::archive::xml_oarchive oa(ofs);
    oa << BOOST_SERIALIZATION_NVP(efh);
    oa << BOOST_SERIALIZATION_NVP(ed);
    //oa.put("</boost_serialization>\r\n"); //needed to mark the end of the archive, otherwise the deserializer's destructor will crash. Interesting design decision.
    //ofs.close();
}

Originally I was just calling ofs.close() and finding that I was getting the crash in the xml_iarchive destructor when the loading function completed. I found two solutions;

  1. Manually write the string </boost_serialization>\r\n to the end of the archive to close the dangling tag
  2. Don't close the stream- let the objects go out of scope at the end of the function and their destructors will do all the cleanup necessary.

I settled on the second option since although I don't like to not close things, it's unclear how to tell the xml_oarchive to clean up, and manually writing the tag that happens to be dangling in this case doesn't guarantee that in a different usage there might be more than one of them that needs closing.

Craig Graham
  • 1,161
  • 11
  • 35