#include #include #include #include #include #include #include struct dummy { template void serialize(Archive& ar, unsigned int version) {} }; int main() { // One-level container // For comparison only. This shows the expected behaviour. { // Create a dummy object in a vector std::vector l(1); // Let pd point to that dummy object dummy* pd = &l.back(); // Serialize and deserialize the vector and the pointer // Here, the order is important: We have to (de)serialize the vector first, // otherwise we run into an issue similar to what is described at // http://www.boost.org/doc/libs/1_57_0/libs/serialization/doc/exceptions.html#pointer_conflict { std::ofstream ofs("one_level.xml"); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(l) << BOOST_SERIALIZATION_NVP(pd); } { std::ifstream ifs("one_level.xml"); boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(l) >> BOOST_SERIALIZATION_NVP(pd); } // Thanks to address tracking, pd still points to the dummy object, // even if the latter is loaded at a different address. assert(&l.back() == pd); // Does not fire } std::cout << std::endl; // Two-level container // This is buggy. { // Create a dummy object in a *nested* vector std::vector> l(1, std::vector(1)); // Again, let pd point to the dummy object dummy* pd = &l.back().back(); // Same as before... { std::ofstream ofs("two_level.xml"); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(l) << BOOST_SERIALIZATION_NVP(pd); } { std::ifstream ifs("two_level.xml"); boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(l) >> BOOST_SERIALIZATION_NVP(pd); } // Again, we would like pd to point to the dummy object, independent // of where it is loaded. This is not the case, however. assert(&l.back().back() == pd); // Does fire!!! } return 0; }