Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-01-07 13:35:39


From: "William E. Kempf" <wekempf_at_[hidden]>
> I don't follow this. How does the user prevent the destructors from
referencing the other
> object(s) participating in the cycle which may no longer exist? The only
safe way to break
> the cycle is to have intimate knowledge about the objects participating in
the cycle and do
> what ever clean up is required in a determistic manner *before* the
object's are destroyed
> and the memory is freed.

(please use line wrapping)

Consider the original example:

struct X
{
    boost::shared_ptr<X> p;
};

int main()
{
    boost::shared_ptr<X> p1(new X);
    boost::shared_ptr<X> p2(new X);

    p1->p = p2;
    p2->p = p1;

    p1.reset();
    p2.reset();

    break_cycles();
}

Here is what break_cycles would do:

1. Find the two X objects (let's call them x1 and x2) on the heap, and scan
them for shared_ptr instances, finding x1.p and x2.p; determine that x1 and
x2 are unreachable.

2. Create a temporary vector< shared_ptr<void> > v and copy x1.p and x2.p
into it.

3. Reset x1.p and x2.p.

4. Clear v. This will cause x1 and x2 to be destroyed.

It's true that, in general, there is no safe way to break the cycle; x1 may
keep a raw pointer to x2, or it might be a X invariant that X::p is
non-empty, causing ~X to fail. This is why the final decision to break the
cycles should be left to the user, and the collector should not
automatically reclaim memory. Still, most reasonable classes would be
collect-friendly.


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