
A couple of suggestions. a) Make Base abstract by including something like virtual ~Base() = 0; This won't address this problem but it can catch accidental "slicing" in other cases. b) The default behavior is to track addresses (thereby detecting cycles, only if a type is serialized through a pointer. Since this doesnt' occur in this program, cycles won't be detected. use serialization traits to set "serialization tracking" always on for the type Base. Robert Ramey Ult Mundane wrote:
Hi,
I'm hitting an assert when I deserialize cycles of shared_ptr<>s. I have the following class hierarchy:
Base <-- Derived Other
Derived holds a shared_ptr<Other>, and Other holds a shared_ptr<Base>.
I have an instance of Derived that points to an instance of Other, which in turn points back to the Derived instance (as a Base pointer). The serialization goes as expected. On deserialization, however, the Base::serialize() and Derived::serialize() are called repeatedly, crashing after the third time -- Other::serialize() is never called.
This problem only happens when the cycle includes a pointer to a base class -- a straightforward a -> b -> a cycle works as expected.
Has anyone else experienced this or found a workaround? It happens in both boost 1.36 and 1.37.0 beta1. I'm using gcc (3.3.5, 3.4.6, and 4.3.2).
Thanks,
Ult
P.S. Attached is the source code illustrating the above example. Here is the output:
Serializing...
Derived Base Base done Other Other done Derived done
Deserializing...
Derived Base Base done Derived Base Base done Derived cycles: ./boost_1_37_0_beta1/libs/serialization/src/basic_iarchive.cpp:436: 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. Aborted
#include <fstream> #include <iostream>
#include
#include #include
#include #include
// Forward declarations class Base; class Derived; class Other;
typedef boost::shared_ptr<Base> BaseRef; typedef boost::shared_ptr<Derived> DerivedRef; typedef boost::shared_ptr<Other> OtherRef;
// For debug output struct Debug { Debug(const char * name) : mName(name) { std::cout << std::string(++sIndentLevel, ' ') << mName << std::endl; }
~Debug() { std::cout << std::string(sIndentLevel--, ' ') << mName << " done" << std::endl; }
static int sIndentLevel; char const * mName; };
int Debug::sIndentLevel = 0;
// Base class Base { public: virtual ~Base() { }
template<class Archive> void serialize(Archive & ar, const unsigned int) { Debug d("Base"); } };
// Derived class Derived : public Base { public: void setOther(OtherRef other) { mOther = other; }
template<class Archive> void serialize(Archive & ar, const unsigned int) { Debug d("Derived");
ar & boost::serialization::base_object<Base>(*this); // This line is executed three times before a crash on deserialzation ar & mOther; // Code after here is never executed on deserialization }
OtherRef mOther; };
// Other class Other { public: void setBase(BaseRef base) { mBase = base; }
template<class Archive> void serialize(Archive & ar, const unsigned int) { Debug d("Other"); ar & mBase; }
BaseRef mBase; };
BOOST_CLASS_EXPORT(Derived);
// main int main(int /* argc */, char * /* argv */[]) { char const * fname = "cycles.text_archive";
std::cout << std::endl << "Serializing..." << std::endl << std::endl;
{ DerivedRef derived(new Derived()); OtherRef other(new Other());
derived->setOther(other); other->setBase(derived);
std::ofstream ofs(fname, std::ios::out | std::ios::binary); boost::archive::text_oarchive oa(ofs);
oa & derived; }
std::cout << std::endl << "Deserializing..." << std::endl << std::endl;
{ Derived derivedCopy;
std::ifstream ifs(fname, std::ios::in | std::ios::binary); boost::archive::text_iarchive ia(ifs);
ia & derivedCopy; } }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users