|
Boost Users : |
From: Tim Taylor (tim_at_[hidden])
Date: 2006-06-09 13:17:32
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 <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
using namespace std;
using namespace boost;
class Item
{
public:
// Constructors/destructor--------------------------
Item(int n = 0)
: _n(n) {
cout << "In Item constructor" << endl;
};
Item(const Item& other) {
cout << "In Item copy constructor" << endl;
_n = other._n;
};
~Item() {
cout << "In Item destructor" << endl;
};
// Data members-------------------------------------
int _n;
// Methods------------------------------------------
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & _n;
}
};
class Bag
{
public:
// Constructors/destructor--------------------------
Bag() {
cout << "In Bag default constructor" << endl;
};
Bag(shared_ptr<Item> item)
: _item(item) {
cout << "In Bag shared_ptr constructor" << endl;
};
Bag(const Bag& other) {
cout << "In Bag copy constructor" << endl;
_item = other._item;
};
~Bag() {
cout << "In Bag destructor" << endl;
};
// Data members-------------------------------------
shared_ptr<Item> _item;
// Methods------------------------------------------
void printUseCount() const {
cout << "Use count: " << _item.use_count() << endl;
}
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & _item;
}
};
int main(int argc, char **argv)
{
const char *filename = "bag.ser";
// create a Bag object with a new Item in it
Bag *pBag = new Bag(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);
const Bag& constBag = *pBag;
oa << constBag;
osSer.close();
pBag->printUseCount();
// delete the original Bag
cout << "About to delete bag 1..." << endl;
delete pBag;
// create a new Bag object
cout << "About to create a new bag..." << endl;
pBag = new Bag;
pBag->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 >> *pBag;
isSer.close();
pBag->printUseCount();
// delete the second BSag
cout << "About to delete bag 2..." << endl;
delete pBag;
return 0;
}
-----
This code produces the following output:
-----
In Item constructor
In Bag shared_ptr constructor
About to serialize bag...
Use count: 1
About to delete bag 1...
In Bag destructor
In Item destructor
About to create a new bag...
In Bag default constructor
Use count: 0
About to deserialize bag...
In Item constructor
Use count: 2
About to delete bag 2...
In Bag destructor
In Item destructor
-----
The series of constructor and destructor calls is as expected. After
the first Bag object is created with a shared_ptr to an Item in it, the
use_count of the shared_ptr is 1. When the first Bag object (including
the shared_ptr) are deleted, and a new, empty Bag object created, the
use_count is now (as expected) 0. However, when the serialization
archive is deserialized into the new Bag object, the use_count of the
shared_ptr jumps from 0 to 2.
Am I doing something silly here, or is this a bug in the shared_ptr
serialization code?
For interest, the saved archive (bag.ser) produced by this code looks
like this:
-----
22 serialization::archive 3 0 0 0 1 2 1 0
0 1
-----
Any help would be much appreciated.
Tim
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