提升序列化:SIGABRT 同时反序列化包含 std::shared_ptr 的对象上的 boost::shared_p

Boost serialization: SIGABRT while deserializing boost::shared_ptr on object containing std::shared_ptr

本文关键字:shared ptr boost 对象 包含 SIGABRT 序列化 升序 反序列化 std      更新时间:2023-10-16

我正在尝试对包含std::shared_ptr的对象执行boost::shared_ptr的序列化和反序列化。

为此,我使用boost::archive::binary_oarchiveboost::archive::binary_iarchive.一切都很顺利,但是当binary_iarchive实例超出范围时,我会得到SIGABRT。这是我的代码:

#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

我正在使用boost 1.62,它允许序列化std::shared_ptr

经过一些研究,我发现,SIGABRT发生在调用类析构函数shared_ptr_helper(相关代码可以在boost库的文件serialization/shared_ptr_helper.hpp中找到)。该类有一个std::map的实例,用于存储反序列化的指针。

std::shared_ptr的序列化代码与boost::shared_ptr(文件serialization/shared_ptr.hpp)几乎相同。实际上,它们都使用单个实例shared_ptr_helper。因此,上面描述的std::map包含两种类型的shared_ptr,但它应该只包含一种类型,这会导致在调用析构函数时产生 SIGABRT。

序列化代码通过上面在serialization/shared_ptr.hpp中定义的 ID 获取帮助程序。如果我们对不同类型的shared_ptr使用不同的 ID,问题就会消失。我确实知道这样做是为了处理序列化指向同一对象的多个指针的情况,但在这种情况下,似乎不太可能有人同时使用std::shared_ptrboost::shared_ptr

那么,这是怎么回事呢?使用这两种类型的shared_ptr是不好的做法,我应该只选择其中一种,或者 boost 中存在错误?

我发现了一个问题,其中讨论了shared_ptr_helper的另一个问题。看起来该类实际上有一些设计缺点,所以就我而言,我应该在我的代码中只留下一种类型的shared_ptr