Boost logo

Boost :

From: George A. Heintzelman (georgeh_at_[hidden])
Date: 2002-02-27 18:39:06


> --- In boost_at_y..., "George A. Heintzelman" <georgeh_at_a...> wrote:
> > Hmm. Yes, but. I am somewhat concerned because pool implementations
> are
> > likely to produce objects which have the same address as previously
> > existing ones of the same type, and I worry that some naivete' here
> may
> > lead someone to problems. I don't have a concrete example though,
> > except of course for deliberate sabotage.
>
> Previously serialized addresses of the same type are fine as long as
> they
> are serialized the same way. The problem occurs only when it is
> serialized different ways. So it turns out that things like maps
> and lists of duplicated pointers, etc work fine. I believe the
> situations where this would be a non-trivial problem - if they exist
> would have to be contrived.

Wait, I'm confused. Could you tell me the behavior of the following:

int * x = new int;
*x = 5;
oarchive << x;
*x = 8;
oarchive << x;

int * y;
iarchive >> y;
int * z;
iarchive >> z;
cout << y << z;

This is like the situation where, if you delete an element from a map,
and add a new (different) one, the two representations *should* be
different, but might not get written out again. I think. Yes the
example is contrived, but I don't think it's that far-fetched to
imagine someone erroneously doing something equivalent.

> > I'm not sure it is that easy to avoid. It would probably be fairly
> > common to give out pointers/references to elements of a map which
> is a
> > data member, for example. I know that I do this frequently. If one
> were
> > writing from scratch, it might be possible to avoid, but to
> retrofit a
> > workaround onto an existing class seems like trouble.
>
> I don't believe this is any problem - I do it all the time see above.

Wait, this is not the same problem. This problem is:

class X {
  map < int, T > mymap;
};
class Y {
  T * p; // Weak pointer or something like it
};

X x; Y y; y.p = &x.mymap[5];

archive << y << x;

iarchive >> y >> x;

Now y's weak pointer isn't 'owned' by anything else, and you will have
a leak. Sure, you 'should have' known better, because you should have
known that destroying x invalidates y, so you need to deal with x
before dealing with y, but is there any way to make this failure more
obvious?

This is a problem with serialization libraries in general. I first
encountered this doing something very similar in ROOT, a physics
analysis package that uses C++ persistence mechanisms. I'm not
necessarily saying you can do anything about it... but I think you
should think about it, and see if there's anything you can do to help
prevent it.

George Heintzelman
georgeh_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk