[Serialization, Signals?] Memory leaks while deserializing derived type

I'm getting memory leaks when deserializing objects and I can't figure out what I'm doing wrong. I'm using VC++ 2005. I've boiled it down to the following code: #include <fstream> // include headers that implement a archive in simple text format #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/shared_ptr.hpp> #include <boost/signal.hpp> // memory leak detection #ifdef _MSC_VER # include <valarray> // doesn't like the free() replacement macro # define _CRTDBG_MAP_ALLOC # include <stdlib.h> # include <crtdbg.h> #endif using boost::signal; class Base : public boost::enable_shared_from_this<Base> { public: typedef boost::shared_ptr<Base> sptr; //virtual ~Base() { } // uncommmenting this causes leaks to disappear private: virtual int virt() = 0; // commenting this line causes leaks to disappear friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { } }; class Derived : public Base { private: int virt() { return 0; } friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & boost::serialization::base_object<Base>(*this); } signal<void (int, const Base::sptr&)> m_derivedSignal1; }; int main(int argc, const char* argv[]) { #ifdef _MSC_VER _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif { Base::sptr loose_derived(new Derived()); } // no leak // create and open a character archive for output std::ofstream ofs("temp_serialize_file"); Base::sptr d_instance(new Derived()); // no leak std::vector<Base::sptr> d_list; d_list.push_back(d_instance); // save data to archive { boost::archive::text_oarchive oa(ofs); oa.register_type<Derived>(); // write class instance to archive oa & d_list; // archive and stream closed when destructors are called } // load data from archive std::vector<Base::sptr> loaded_d; { std::ifstream ifs("temp_serialize_file", std::ios::binary); boost::archive::text_iarchive ia(ifs); ia.register_type<Derived>(); // read class state from archive ia & loaded_d; // archive and stream closed when destructors are called // loaded instance has leak in memory allocated in boost signals } return 0; } Any ideas would be very appreciated. Brad Anderson

On 25 Jul 2008, at 13:53, Brad Anderson wrote:
I'm getting memory leaks when deserializing objects and I can't figure out what I'm doing wrong. I'm using VC++ 2005. I've boiled it down to the following code:
Just a quick guess:
//virtual ~Base() { } // uncommmenting this causes leaks to disappear
The base class needs a virtual destructor, thus uncommenting this is needed. Matthias

On Fri, Jul 25, 2008 at 5:28 PM, Matthias Troyer <troyer@phys.ethz.ch> wrote:
On 25 Jul 2008, at 13:53, Brad Anderson wrote:
I'm getting memory leaks when deserializing objects and I can't figure out
what I'm doing wrong. I'm using VC++ 2005. I've boiled it down to the following code:
Just a quick guess:
//virtual ~Base() { } // uncommmenting this causes leaks to disappear
The base class needs a virtual destructor, thus uncommenting this is needed.
I solved my problem seconds before I got your message :). I had actually done that in what I thought was the class giving issue but it turns out I had several base classes that were missing virtual destructors so that fix didn't appear to work because I was still getting tons of leaks. I am curious, though, about why the leaks only happened in when I deserialized and not in any of the other instances I created myself. Does shared_ptr perform some kind of trickery to detect the type to delete through, even when the shared_ptr is typed for the base class?
Matthias

AMDG Brad Anderson wrote:
I am curious, though, about why the leaks only happened in when I deserialized and not in any of the other instances I created myself. Does shared_ptr perform some kind of trickery to detect the type to delete through, even when the shared_ptr is typed for the base class?
Yes. A shared_ptr captures the type to delete through when it is constructed. In Christ, Steven Watanabe

On Fri, Jul 25, 2008 at 11:47 PM, Steven Watanabe <watanabesj@gmail.com>wrote:
AMDG
Brad Anderson wrote:
I am curious, though, about why the leaks only happened in when I deserialized and not in any of the other instances I created myself. Does shared_ptr perform some kind of trickery to detect the type to delete through, even when the shared_ptr is typed for the base class?
Yes. A shared_ptr captures the type to delete through when it is constructed.
In Christ, Steven Watanabe
Good to know. Thanks.
participants (3)
-
Brad Anderson
-
Matthias Troyer
-
Steven Watanabe