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