#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost; using namespace std; class ChildClass { public: friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int version) { // Leaks are worse if the child has data: // //ar & mData; } // Leaks are worse if the child has data: // //map>> mData; }; class MyClass { public: MyClass() {}; ~MyClass() {}; void WriteToFile(const char* file_name) { std::ofstream out_stream(file_name, ios::binary); boost::archive::binary_oarchive out_archive(out_stream); out_archive << mData; } static shared_ptr ReadFromFile(const char* file_name) { shared_ptr ret ( new MyClass() ); ifstream in_stream(file_name, ios::binary); boost::archive::binary_iarchive in_archive(in_stream); in_archive >> ret->mData; return ret; } map > mData; void Print(ostream& str) { str << "MyClass @" << ((int)(void*)this) << " with " << mData.size() << " children" << endl; typedef pair> pairt1; BOOST_FOREACH( pairt1& ii, mData ) {/* str << ii.first << " => " << ii.second->mData.size() << " row(s)" << endl; typedef pair>> pairt2; BOOST_FOREACH( pairt2& jj, ii.second->mData ) { str << " " << jj.first << " => [" << endl; BOOST_FOREACH( vector& kk, jj.second ) { str << " ["; BOOST_FOREACH( float& ll, kk ) { str << ll << ", "; } str << "]" << endl; } str << " ]" << endl; }*/ } } }; BOOST_AUTO_TEST_CASE( boost_serialisation_mem_leak ) { // create a bit of data shared_ptr new_item(new MyClass()); // new_item must have children for the mem leak to occur new_item->mData["foo"] = shared_ptr(new ChildClass()); // having data in the child is not necessary for mem leak // // new_item->mData["foo"]->mData["bar"].push_back(vector(2, 3.0)); // new_item->mData["foo"]->mData["bar"].push_back(vector(1, 7.0)); new_item->Print(cout); // save & load it new_item->WriteToFile("test.bin"); shared_ptr loaded_item = MyClass::ReadFromFile("test.bin"); cout << endl << endl; loaded_item->Print(cout); }