[serialization] deletion of unconstucted objects

Hi. I am found that if object, 1) loaded via pointer 2) throws exception in its constructor, while loadind then destructor for this object will be erroneously called Test code: #define BOOST_SERIALIZATION_DYN_LINK #include <boost/archive/polymorphic_iarchive.hpp> #include <boost/archive/polymorphic_oarchive.hpp> #include <boost/archive/polymorphic_xml_iarchive.hpp> #include <boost/archive/polymorphic_xml_oarchive.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/export.hpp> #include <sstream> #include <iostream> struct A { int * p_; A() : p_(new int(10)) {} ~A() { std::cout << *p_; delete p_; } template <class Ar> void serialize(Ar & ar, const unsigned int file_version) { ar & boost::serialization::make_nvp("p", *p_); } }; struct B { A x_; int z_; B(int z) : z_(z) {} B() { throw std::runtime_error("test"); } template <class Ar> void serialize(Ar & ar, const unsigned int file_version) { ar & BOOST_SERIALIZATION_NVP(z_); ar & BOOST_SERIALIZATION_NVP(x_); } }; int main(int argc, char* argv[]) { try { std::stringstream s; { B b(0); B *pb = &b; b.z_ = 5; boost::archive::polymorphic_xml_oarchive ar(s); ar & BOOST_SERIALIZATION_NVP(pb); } { B *pb; boost::archive::polymorphic_xml_iarchive ar(s); ar & BOOST_SERIALIZATION_NVP(pb); delete pb; } } catch (std::runtime_error&) {} return 0; } Tested with boost 1.33.1 on MSVC 8. Member variable B::x_ deleted twice. I see strange piece of code in boost\archive\detail\iserializer.hpp: // catch exception during load_construct_data so that we don't // automatically delete the t which is most likely not fully // constructed BOOST_TRY { // this addresses an obscure situtation that occurs when // load_constructor de-serializes something through a pointer. ar.next_object_pointer(t); boost::serialization::load_construct_data_adl<Archive, T>( ar_impl, t, file_version ); } BOOST_CATCH(...){ BOOST_RETHROW; } BOOST_CATCH_END Its look like that operator delete(ap.release()); or other code that detaches ap missing before BOOST_RETHROW. I had not tested my sample with current CVS version, but had not found any changes in this code and suppose that this error still persists.

Looks correct to me - I've patched my local version with checkin pending local testing. Robert Ramey Sergey Skorniakov wrote:
Hi. I am found that if object, 1) loaded via pointer 2) throws exception in its constructor, while loadind then destructor for this object will be erroneously called
Test code:
#define BOOST_SERIALIZATION_DYN_LINK #include <boost/archive/polymorphic_iarchive.hpp> #include <boost/archive/polymorphic_oarchive.hpp> #include <boost/archive/polymorphic_xml_iarchive.hpp> #include <boost/archive/polymorphic_xml_oarchive.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/export.hpp> #include <sstream> #include <iostream> struct A { int * p_; A() : p_(new int(10)) {} ~A() { std::cout << *p_; delete p_; } template <class Ar> void serialize(Ar & ar, const unsigned int file_version) { ar & boost::serialization::make_nvp("p", *p_); } }; struct B { A x_; int z_; B(int z) : z_(z) {} B() { throw std::runtime_error("test"); } template <class Ar> void serialize(Ar & ar, const unsigned int file_version) { ar & BOOST_SERIALIZATION_NVP(z_); ar & BOOST_SERIALIZATION_NVP(x_); } }; int main(int argc, char* argv[]) { try { std::stringstream s; { B b(0); B *pb = &b; b.z_ = 5; boost::archive::polymorphic_xml_oarchive ar(s); ar & BOOST_SERIALIZATION_NVP(pb); } { B *pb; boost::archive::polymorphic_xml_iarchive ar(s); ar & BOOST_SERIALIZATION_NVP(pb); delete pb; } } catch (std::runtime_error&) {} return 0; }
Tested with boost 1.33.1 on MSVC 8. Member variable B::x_ deleted twice. I see strange piece of code in boost\archive\detail\iserializer.hpp:
// catch exception during load_construct_data so that we don't // automatically delete the t which is most likely not fully // constructed BOOST_TRY { // this addresses an obscure situtation that occurs when // load_constructor de-serializes something through a pointer. ar.next_object_pointer(t); boost::serialization::load_construct_data_adl<Archive, T>( ar_impl, t, file_version ); } BOOST_CATCH(...){ BOOST_RETHROW; } BOOST_CATCH_END
Its look like that operator delete(ap.release()); or other code that detaches ap missing before BOOST_RETHROW. I had not tested my sample with current CVS version, but had not found any changes in this code and suppose that this error still persists. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Robert Ramey
-
Sergey Skorniakov