0

I am trying to perform serialization and deserialization of boost::shared_ptr on the object containing std::shared_ptr.

To do that, I use boost::archive::binary_oarchive and boost::archive::binary_iarchive. Everything is going just fine, but when binary_iarchive instance goes out of scope, I get SIGABRT. Here is my code:

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/serialization.hpp>

#include <boost/serialization/shared_ptr.hpp>
#include <sstream>

#include <boost/shared_ptr.hpp>

class SomeClass
{
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int file_version) {
    }
};

class ClassWithStdSharedPointer
{
public:
    std::shared_ptr<SomeClass> ptr_to_someclass;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int file_version)
    {
        ar & ptr_to_someclass;
    }
};

int main()
{
    boost::shared_ptr<const ClassWithStdSharedPointer> ptr_to_save;
    ptr_to_save = boost::make_shared<ClassWithStdSharedPointer>();

    std::ostringstream ostream;
    boost::archive::binary_oarchive oa(ostream);
    oa << ptr_to_save;

    std::string serialized_buffer = ostream.str();
    std::istringstream istream(serialized_buffer);

    {
        boost::archive::binary_iarchive ia(istream);

        boost::shared_ptr<ClassWithStdSharedPointer> ptr_to_load;

        ia >> ptr_to_load;
    } 
} // the problem appears when you get to this line

I am using boost 1.62, which allows to serialize std::shared_ptr's.

After some research I figured out, that SIGABRT occurs when shared_ptr_helper class destructor is called (relevant code can be found in file serialization/shared_ptr_helper.hpp of boost library). That class has an instance of std::map, which is used to store deserialized pointers.

Serialization code for std::shared_ptr is almost the same as for boost::shared_ptr (file serialization/shared_ptr.hpp). In fact, they both use single instance of shared_ptr_helper. Therefore, std::map described above contains both types of shared_ptr's, but it supposed to contain only one type, and this causes SIGABRT when destructor is called.

Serialization code gets helper by ID defined above in serialization/shared_ptr.hpp. If we use different ID's for different types of shared_ptr's, the problem disappears. I do understand that this is done to handle situations when multiple pointers to the same object are serialized, but it seems very unlikely that someone would use both std::shared_ptr and boost::shared_ptr in that case.

So, what is going on here? Using both types of shared_ptr's is bad practice and I should just choose one of them, or there is a bug in boost?

1 Answers1

0

I've found a question where another problem with shared_ptr_helper is discussed. It looks like that class actually has some design drawbacks, so in my case I should just leave only one type of shared_ptr's in my code.