Я пытаюсь выполнить сериализацию и десериализацию boost::shared_ptr
для объекта, содержащего std::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
(соответствующий код можно найти в файле serialization/shared_ptr_helper.hpp
библиотеки boost). У этого класса есть экземпляр std::map
, который используется для хранения десериализованных указателей.
Код сериализации для std::shared_ptr
почти такой же, как для boost::shared_ptr
(файл serialization/shared_ptr.hpp
). На самом деле они оба используют один экземпляр shared_ptr_helper
. Следовательно, std::map
, описанный выше, содержит оба типа shared_ptr
, но он должен содержать только один тип, и это вызывает SIGABRT при вызове деструктора.
Сериализационный код получает помощник по идентификатору, указанному выше в serialization/shared_ptr.hpp
. Если мы используем разные идентификаторы для разных типов shared_ptr
, проблема исчезнет. Я понимаю, что это делается для обработки ситуаций, когда несколько указателей на один и тот же объект сериализуются, но очень маловероятно, что в этом случае кто-то будет использовать как std::shared_ptr
, так и boost::shared_ptr
.
Итак, что здесь происходит? Использование обоих типов shared_ptr
- это плохая практика, и я должен просто выбрать один из них, или есть ошибка в boost?