10

I Have a object which the following field :

boost::unordered_map<std::string, std::shared_ptr<Foo> > m_liste_;

I would like to serialize it, but it seems std::shared_ptr can't be serialized in a simple manner

anyone have a solution ?

Etienne de Martel
  • 34,692
  • 8
  • 91
  • 111
Guillaume Paris
  • 10,303
  • 14
  • 70
  • 145
  • Did you mean to write `boost::shared_ptr` rather than `std::shared_ptr`? – aldo Mar 30 '12 at 16:32
  • yes initally I would like to use std::shared_ptr, but with boost::shared_ptr and correct #include all is fine so I will stay with boost,thanks for your comment. – Guillaume Paris Apr 02 '12 at 09:42

2 Answers2

16

I suspect you are missing an include,

#include <boost/serialization/shared_ptr.hpp>

link, at the bottom

Also, the example makes it look like aliasing and cycles are taken care of by default.

_Of course, having cycles will lead to potential memory leaks with shared_ptr that have nothing to do with serialization, and you'll still have to heed those (by avoiding cycles or judicious use of weak_ptr)_

See also:

sehe
  • 374,641
  • 47
  • 450
  • 633
-5

Unfortunately the answer is that there isn't a simple way to serialise anything with pointers in it, because the memory layout of your data is likely to be different when you load it back in. A serialiser capable of dealing with pointers would need to be very smart, and come up with a 'memory layout' to save to disc that had valid pointer addresses in it for the stored structure, and which then rewrote them as the structure was deserialised in order to get the pointers pointing to the right places after loading is complete.

The really fun part is that if you allow pointers in serialisable structures you have to be able to cope with cyclic reference graphs. Also, shared_ptr keeps internal reference counts and accounting information so that it knows when to destroy an object, so the serialiser would need to know all about how that works as well, in order to correctly record reference counts (and ignore references from shared_ptr objects which aren't inside the serialised tree but do point to thinks inside it).

Basically it's a giant headache, and that's why serialisation libraries don't do it by default. You usually end up needing quite specific custom behaviour if you want to do it, so they leave it up to you to implement that in order to ensure it's done correctly.

Matthew Walton
  • 9,809
  • 3
  • 27
  • 36
  • 2
    Now, are you suggesting that Boost Serialization can't cope with the complexities you mention? I'm quite sure that it can. See the tutorial demo: http://www.boost.org/doc/libs/1_49_0/libs/serialization/example/demo.cpp – sehe Mar 30 '12 at 14:07
  • Nothing in that example serialises anything with pointers in it save for STL containers (which of course use them internall), which it explicitly notes already have specific support in the serialisation library. However, that example does show how to provide serialisation behaviour for your own types, which is the hook you use to serialise anything the library can't handle with its default knowledge. – Matthew Walton Mar 30 '12 at 14:12
  • `std::list > schedule;` and `typedef bus_stop * bus_stop_pointer; std::list stops;` - and **yes** bus stops are shared between routes. I wonder what link _you_ clicked? – sehe Mar 30 '12 at 14:17
  • Oh and that 'knowledge of implementing your classes' is (a) `ar & stops;` for bus_route and (b) `ar & schedule` for bus_schedule. The only added 'magic' is registering the polymorphic types for deserialization. – sehe Mar 30 '12 at 14:20