$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Sergey Skorniakov (s.skorniakov_at_[hidden])
Date: 2007-03-23 04:07:53
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.