Boost logo

Boost Users :

Subject: Re: [Boost-users] [multi-index] Container not safe against reentrant clear() / erase() ?
From: joaquin_at_[hidden]
Date: 2009-06-03 11:12:08


Sebastian Theophil escribió:
>
> Hi,
>
>
>
> I have encounted a scenario that triggers an access violation when
> removing reference counted objects from a container.
>
>
>
> Assume I have a (for simplicity's sake, global) multi_index_container
> g_multiindex containing reference counted objects of type CObject:
>
>
>
> boost::multi_index_container< ordered_unique< shared_ptr<CObject> > >
> g_multiindex;
>
>
>
> In general, an object of type CObject may be destroyed at any time and
> the destructor makes sure to remove any reference held in g_multiindex:
>
>
>
> class CObject {
>
> ~CObject() {
>
> // if object is explicitly destroyed, remove from container
>
> g_multiindex.erase( this );
>
> }
>
> };
>
>
>

If I'm understanding this right, I think your design is flawed. You say
that CObjects
detach themselves from g_multiindex when their refcount drops to 0, but:
how can
this count be zero if the CObject is still referenced from g_multiindex?
The only
situation where this can happen is when destroying g_multiindex,
precisely where
the crash occurs. Simply omitting the g_multiindex.erase invocation inside
~CObject should fix things.

Am I wrong somewhere?

> [...]
>
>
>
> This would remove all elements from the container before actually
> deleting them. I'm unsure though how the same behavior could be
> achieved when erasing a single element.
>
>
>
> The C++ standard does not seem to define how clear() and erase()
> should behave in this regard, but I cannot image that my application
> scenario is so unusual that this problem has not been solved a million
> times. So I'm curious if the behavior of multi_index_containers is by
> design and maybe someone could be so kind to enlighten me why this is
> so. Is there any better way to achieve what I'm trying to do?
>

This is simply an uncovered situation, and, IMHO, a very unusual one
--in support
of my view I can say I never got a report on this, and the lib's been
around for
4.5 years.

On the other hand, erasing inside erase() does work; presumably this is much
more frequent, for instance when working with composite and tree-like
data types.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


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