Boost 序列化:SIGABRT 同时对包含 std::shared_ptr 的对象反序列化 boost::shared_ptr
Boost serialization: SIGABRT while deserializing boost::shared_ptr on object containing std::shared_ptr
我正在尝试对包含 std::shared_ptr
的对象执行 boost::shared_ptr
的序列化和反序列化。
为此,我使用 boost::archive::binary_oarchive
和 boost::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
class析构函数被调用时(相关代码可以在boost库的文件serialization/shared_ptr_helper.hpp
中找到)。 class 有一个 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_ptr
和 boost::shared_ptr
。
那么,这是怎么回事?使用两种类型的 shared_ptr
是不好的做法,我应该只选择其中一种,或者 boost 中存在错误?
我找到了 question,其中讨论了 shared_ptr_helper
的另一个问题。看起来 class 实际上有一些设计缺陷,所以在我的例子中,我应该只在我的代码中保留一种类型的 shared_ptr
。
我正在尝试对包含 std::shared_ptr
的对象执行 boost::shared_ptr
的序列化和反序列化。
为此,我使用 boost::archive::binary_oarchive
和 boost::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
class析构函数被调用时(相关代码可以在boost库的文件serialization/shared_ptr_helper.hpp
中找到)。 class 有一个 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_ptr
和 boost::shared_ptr
。
那么,这是怎么回事?使用两种类型的 shared_ptr
是不好的做法,我应该只选择其中一种,或者 boost 中存在错误?
我找到了 question,其中讨论了 shared_ptr_helper
的另一个问题。看起来 class 实际上有一些设计缺陷,所以在我的例子中,我应该只在我的代码中保留一种类型的 shared_ptr
。