Boost logo

Boost Users :

Subject: Re: [Boost-users] [serialization] Memory leaks even with shared_ptrs
From: Hazrat Pradipta Ranjali (mrdipta_at_[hidden])
Date: 2011-07-22 04:02:57


when you create a Base class, make sure that the destructor is to be
declared as virtual.

On Fri, Jul 22, 2011 at 04:55, cc caprani <cc.caprani_at_[hidden]> wrote:

> On Thu, Jul 21, 2011 at 8:32 PM, cc caprani <cc.caprani_at_[hidden]> wrote:
>
>>
>> This very simple program still leaks one copy of everything loaded from
>> the archive.
>>
>>
> I've done some more on this and the leak only occurs if a virtual member
> function is declared in the base class. It doesn't matter if the function is
> pure virtual or concrete, and whether or not
> BOOST_SERIALIZATION_ASSUME_ABSTRACT is used. Turning off both virtual base
> class member functions removes the leak.
>
> At this stage I think it must be a bug - should I form a tracker for it? Or
> am I not understanding something?
>
> Here is a minimal program to replicate the leak (using VS2010, boost 1.47).
>
>
> #include <boost/archive/xml_iarchive.hpp>
> #include <boost/archive/xml_oarchive.hpp>
> #include <boost/serialization/vector.hpp>
> #include <boost/serialization/export.hpp>
> #include <boost/serialization/shared_ptr.hpp>
> #include <boost/shared_ptr.hpp>
> #include <boost/make_shared.hpp>
> #include <iostream>
> #include <fstream>
> #include <crtdbg.h>
>
>
> class Distribution
> {
> public:
> Distribution(void) {};
> ~Distribution(void) {};
> // turn on either to get memory leak
> virtual int getType() = 0;
> //virtual int getType() {return 1;};
>
>
> private:
> friend class boost::serialization::access;
> template<class Archive>
> void serialize(Archive& ar, const unsigned int version) {};
> };
> typedef boost::shared_ptr<Distribution> DistributionPtr;
> BOOST_SERIALIZATION_ASSUME_ABSTRACT(Distribution)
>
> class ContinuousDist : public Distribution
> {
> public:
> ContinuousDist(){};
> ~ContinuousDist(void) {};
> virtual int getType() {return 1;};
>
>
> private:
> friend class boost::serialization::access;
> template<class Archive>
> void serialize(Archive& ar, const unsigned int version)
> { ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Distribution); };
>
> };
> BOOST_CLASS_EXPORT(ContinuousDist);
>
> class DiscreteDist : public Distribution
> {
> public:
> DiscreteDist(void)
> {
> m_Data.push_back(4.0);
> m_Data.push_back(8.0);
> };
> ~DiscreteDist(void){};
> virtual int getType() {return 2;};
>
>
> private:
> std::vector<double> m_Data;
>
> friend class boost::serialization::access;
> template<class Archive>
> void serialize(Archive& ar, const unsigned int version)
> {
> ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Distribution)
> & BOOST_SERIALIZATION_NVP(m_Data);
> };
> };
> BOOST_CLASS_EXPORT(DiscreteDist);
>
> class Parameter
> {
> public:
> Parameter(){};
> Parameter(int type)
>
> {
> if(type == 1)
> m_pDist = boost::make_shared<DiscreteDist>();
> else
> m_pDist = boost::make_shared<ContinuousDist>();
> };
> ~Parameter(void){};
>
> private:
> DistributionPtr m_pDist;
>
>
> friend class boost::serialization::access;
> template<class Archive>
> void serialize(Archive& ar, const unsigned int version)
> { ar & BOOST_SERIALIZATION_NVP(m_pDist); };
>
> };
> typedef boost::shared_ptr<Parameter> ParameterPtr;
>
> void load(std::vector<ParameterPtr>& vP, std::string file)
> {
> std::ifstream ifs(file.c_str());
> boost::archive::xml_iarchive ia(ifs);
> ia >> BOOST_SERIALIZATION_NVP(vP);
> }
>
> void save(std::vector<ParameterPtr>& vP, std::string file)
> {
> std::ofstream ofs(file.c_str());
> boost::archive::xml_oarchive oa(ofs);
> oa << BOOST_SERIALIZATION_NVP(vP);
> }
>
> int main()
> {
> _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
>
> // the file to read/save from/to
> std::string file = "archive.xml";
>
> // make some Parmeters
> std::vector<ParameterPtr> vParam;
> vParam.push_back( boost::make_shared<Parameter>(1) );
> vParam.push_back( boost::make_shared<Parameter>(2) );
>
>
> // save the file
> std::cout << "Writing..." << std::endl;
> save(vParam,file);
>
> // clear it
> vParam.clear();
>
> // read the file
> std::cout << "Reading..." << std::endl;
> load(vParam,file);
>
> return 0;
> }
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net