[serialization] assert loading shared_ptr to abstract base class using boost 1.35.0
Hi there,
Using the boost::serialization library, I'm hitting an
assert while deserializing. It happens only in a specific
set of circumstances requiring a shared_ptr to an abstract
base class.
Class "Derived" is derived from class "AbstractBase" which
is abstract. I'm serializing two objects which are of type
shared_ptr<AbstractBase> that point to objects of type
Derived. After the two shared_ptr's are serialized to disk,
when I read them back in I hit an assert in
basic_iarchive.cpp: "Assertion `new_cid == cid' failed".
This assert happens on the second object only.
As far as I can tell from the serialization documentation, I
am using the appropriate BOOST_CLASS_EXPORT() line for the
derived class, as well as registering the base-derived
relationship with base_object(), and I even threw in a
couple of BOOST_SERIALIZATION_SHARED_PTR() calls for good
measure although I don't think they do anything in my
environment.
Two additional pieces of information:
- If the base class is not abstract, but I still use
BOOST_IS_ABSTRACT(), I get the same assert. This might
indicate that some necessary polymorphism code isn't being
generated as a result of declaring the class abstract.
- If I serialize the pointers directly instead of using
shared_ptr, it does not hit the assert.
I have a workaround for this problem: it works as expected
if I define the load_construct_data() template function for
the base class do to nothing (assert), instead of using the
BOOST_IS_ABSTRACT() macro.
Attached is the minimal code to reproduce the problem. I'm
using boost 1.35.0 with gcc 3.3.5 on Linux (RHEL4). Is there
something I'm missing to make this work?
Thanks in advance,
Ult
#include <fstream>
#include
I think I fixed this in the trunk. Robert Ramey Ult Mundane wrote:
Hi there,
Using the boost::serialization library, I'm hitting an assert while deserializing. It happens only in a specific set of circumstances requiring a shared_ptr to an abstract base class.
Class "Derived" is derived from class "AbstractBase" which is abstract. I'm serializing two objects which are of type shared_ptr<AbstractBase> that point to objects of type Derived. After the two shared_ptr's are serialized to disk, when I read them back in I hit an assert in basic_iarchive.cpp: "Assertion `new_cid == cid' failed". This assert happens on the second object only.
As far as I can tell from the serialization documentation, I am using the appropriate BOOST_CLASS_EXPORT() line for the derived class, as well as registering the base-derived relationship with base_object(), and I even threw in a couple of BOOST_SERIALIZATION_SHARED_PTR() calls for good measure although I don't think they do anything in my environment.
Two additional pieces of information: - If the base class is not abstract, but I still use BOOST_IS_ABSTRACT(), I get the same assert. This might indicate that some necessary polymorphism code isn't being generated as a result of declaring the class abstract. - If I serialize the pointers directly instead of using shared_ptr, it does not hit the assert.
I have a workaround for this problem: it works as expected if I define the load_construct_data() template function for the base class do to nothing (assert), instead of using the BOOST_IS_ABSTRACT() macro.
Attached is the minimal code to reproduce the problem. I'm using boost 1.35.0 with gcc 3.3.5 on Linux (RHEL4). Is there something I'm missing to make this work?
Thanks in advance,
Ult
#include <fstream>
#include
#include #include
#include #include class AbstractBase { public: AbstractBase() : mInt(-1) { } virtual ~AbstractBase() { }
virtual void func() const = 0;
template<class Archive> void serialize(Archive & ar, const unsigned int) { ar & mInt; }
int mInt; };
BOOST_IS_ABSTRACT(AbstractBase); BOOST_SERIALIZATION_SHARED_PTR(AbstractBase); BOOST_CLASS_IMPLEMENTATION(AbstractBase, boost::serialization::object_serializable);
class Derived : public AbstractBase { public: Derived() : mInt2(-2) { }
void func() const { }
template<class Archive> void serialize(Archive & ar, const unsigned int) { ar & boost::serialization::base_object<AbstractBase>(*this); ar & mInt2; } int mInt2; };
BOOST_CLASS_EXPORT(Derived); BOOST_SERIALIZATION_SHARED_PTR(Derived); BOOST_CLASS_IMPLEMENTATION(Derived, boost::serialization::object_serializable);
int main(int /* argc */, char * /* argv */[]) { char const * fname = "abstract.out";
boost::shared_ptr<AbstractBase> baseA(new Derived()); boost::shared_ptr<AbstractBase> baseB(new Derived());
{ std::ofstream ofs(fname, std::ios::out | std::ios::binary); boost::archive::text_oarchive oa(ofs);
oa & baseA; oa & baseB; }
{ std::ifstream ifs(fname, std::ios::in | std::ios::binary); boost::archive::text_iarchive ia(ifs);
ia & baseA; std::cout << "The following line asserts:" << std::endl; ia & baseB; // Assertion `new_cid == cid' failed
// Full text of assert: // // /dev/libs/boost_1_35_0/libs/serialization/src/basic_iarchive.cpp:432: const boost::archive::detail::basic_pointer_iserializer* boost::archive::detail::basic_iarchive_impl::load_pointer(boost::archive::detail::basic_iarchive&, void*&, const boost::archive::detail::basic_pointer_iserializer*, const boost::archive::detail::basic_pointer_iserializer*(*)(const boost::serialization::extended_type_info&)): Assertion `new_cid == cid' failed.
} }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Robert Ramey
-
Ult Mundane