Problem with serialization of shared_ptr (with example code)

Hi,
I am having some troubles with serialization of shared_ptrs. The basic
problem is that when I serialize a shared_ptr, then later deserialize
into a new shared_ptr, the use_count of the new pointer is, incorrectly
(as far as I can see), 2 rather than 1.
I am using boost 1.33.1 and gcc 4.0.1.
Here is some example code to demonstrate the problem:
-----
// compile with:
// gcc -o ptrser-test ptrser-test.cpp -lstdc++ -lboost_serialization-gcc
#include <iostream>
#include <fstream>
#include

Tim Taylor wrote:
Hi,
I am having some troubles with serialization of shared_ptrs. The basic problem is that when I serialize a shared_ptr, then later deserialize into a new shared_ptr, the use_count of the new pointer is, incorrectly (as far as I can see), 2 rather than 1.
I am using boost 1.33.1 and gcc 4.0.1.
Try destroying the archive object and check the use count again. The archive probably keeps its own temporary copy of the shared_ptr.

I'm concerned that the input put archive is not destroyed soon enough. It has to hold a copy of the shared pointer as long its open. Try the following changes: (I've simplified it a little) int main(int argc, char **argv) { const char *filename = "bag.ser"; { const Bag b(shared_ptr<Item>(new Item(1))); // now serialize the Bag cout << "About to serialize bag..." << endl; ofstream osSer(filename); boost::archive::text_oarchive oa(osSer); oa << b; b.printUseCount(); cout << "About to delete bag 1..." << endl; } // no need for stream close, archive and stream closed automatically cout << "About to create a new bag..." << endl; Bag b1; { b1.printUseCount(); // and deserialize it into the new Bag object cout << "About to deserialize bag..." << endl; ifstream isSer(filename, std::ios::binary); boost::archive::text_iarchive ia(isSer); ia >> b1; b1.printUseCount(); // should equal 2 - b1 plus one in the archive } // close all streams and archives b1.printUseCount(); // should equal 1 - b1 plus one in the archive return 0; } I haven't tested this - if it doesn't work as expected - my name is mud here. Robert Ramey

Hi Peter and Robert, Many thanks for your replies. Destroying the input archive solves the problem. Best wishes, Tim Robert Ramey wrote:
I'm concerned that the input put archive is not destroyed soon enough. It has to hold a copy of the shared pointer as long its open. Try the following changes: (I've simplified it a little)
int main(int argc, char **argv) { const char *filename = "bag.ser"; { const Bag b(shared_ptr<Item>(new Item(1))); // now serialize the Bag cout << "About to serialize bag..." << endl; ofstream osSer(filename); boost::archive::text_oarchive oa(osSer); oa << b; b.printUseCount(); cout << "About to delete bag 1..." << endl; } // no need for stream close, archive and stream closed automatically cout << "About to create a new bag..." << endl; Bag b1; { b1.printUseCount(); // and deserialize it into the new Bag object cout << "About to deserialize bag..." << endl; ifstream isSer(filename, std::ios::binary); boost::archive::text_iarchive ia(isSer); ia >> b1; b1.printUseCount(); // should equal 2 - b1 plus one in the archive } // close all streams and archives b1.printUseCount(); // should equal 1 - b1 plus one in the archive return 0; }
I haven't tested this - if it doesn't work as expected - my name is mud here.
Robert Ramey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Peter Dimov
-
Robert Ramey
-
Tim Taylor