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 );
}
};
Since ownership of CObject is shared, g_multiindex may hold
the last reference to a CObject instance.
g_multiindex.clear then calls
- delete_all_nodes()
- delete_all_nodes(root())
- this->final_delete_node_(static_cast<final_node_type*>(x));
- which first calls the
destructor on x (i.e. it calls ~CObject() on the root() node)
At this point, the multi_index_container is not in a valid
state. The root() node is being deleted but the container still contains the
root() node and points to it, empty() would certainly still return false.
Calling g_multiindex.erase with a compatible key crashes in my case.
In general, it seems to me that it would be safer to
implement clear() by doing something like:
void clear() {
multi_index_container cpy;
swap(cpy, *this);
cpy.clear();
}
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?
Thank you very much,
Sebastian
--
Sebastian Theophil (stheophil@think-cell.com)
Software Engineer
think-cell Software GmbH | http://www.think-cell.com | |
Invalidenstr. 34 | phone | +49-30-666473-10 |
10115 Berlin, Germany | toll-free (US) | +1-800-891-8091 |
Directors: Dr. Markus Hannebauer, Dr. Arno Schoedl | ||
Amtsgericht Berlin-Charlottenburg, HRB 85229 |