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