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
On Thu, Jul 21, 2011 at 8:32 PM, cc caprani
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
#include #include #include #include #include #include #include <iostream> #include <fstream> #include 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@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users