tags:

views:

365

answers:

4

I have an application which creates objects of a certain kind (let's say, of "Foo" class) during execution, to track some statistics, and insert them into one or both of two STL maps, say:

map<Foo*, int> map1;
map<Foo*, int> map2;

I was wondering what is the best way to delete the Foo objects. At the moment my solution is to iterate over map1 and map2, and put the Foo pointers into a set, then interating on this set and call delete on each.

Is there a more effective way, possibly using auto_ptr? If so how, since auto_ptr<> objects can't be stored in STL containers?

Thanks in advance.

+7  A: 

Use boost::shared_ptr - it's specifically intended for cases where the object can be referenced from multiple locations. Using auto_ptr is not an option here - once the first auto_ptr to an object is destroyde the second one is left with a dangling pointer and that's direct way to undefined behaviour.

sharptooth
I was just typing the same thing when yours appeared. One extra comment I had: if you can't use shared_ptr, you could also consider using intrusive_pointer.See http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/smart_ptr.htm for full documentation.
a1kmm
Usage of auto_ptr in this context is prevented by non-const arguemtn in copy constructor. There is no undefined behaviour auto_ptr in STL containers won't make compileable code.
Basilevs
@Basilevs: It's a good practice of Standard Library implementors to prevent it. They do not have to do so: the Standard merely makes it Undefined Behavior, and "not compiling" is a very good choice of UB.
MSalters
+10  A: 

auto_ptr objects cannot, as you say, be stored in STL containers. I like to use the shared_ptr object (from boost) for this purpose. It is a referenced counted pointer, so the object will be deleted once only, when it goes out of scope.

typedef<shared_ptr<Foo>, int> Map;
Map map1;
Map map2;

Now, you just add and remove from map1 and map2, shared_ptr objects as they were pointers, and they will take care of the deletion, when the last reference is removed.

1800 INFORMATION
I guess you meant "when it is no longer referenced", not "when it goes out of scope". Scope would be hard to define in this situation.
sharptooth
Maybe I don't understand the question itself, but what's the use of shared_ptr here? To delete "Foo" objects, he must still iterate over the maps and delete them (shared_ptr won't delete the object, until the last reference on it is removed)... What he needs there is an "active" pointer. The one, that becomes invalidated if the object is deleted...
SadSido
Since you are directly storing the shared pointer objects in the map, they will take care of ownership of the "Foo", and it will be deleted when the last shared_ptr object is destroyed. @sharptooth - you are correct, I should have more accurately referred to the ownership of the reference, not to scope
1800 INFORMATION
@SadSido - the concept of the shared pointer is to avoid the requirement for having unique ownership - by sharing the ownership, you don't need to know in your code which one holds the last reference
1800 INFORMATION
+1  A: 

http://ootips.org/yonat/4dev/smart-pointers.html talks about certain kinds of smart pointers that may be storeable in STL containers. See here

Preet Sangha
+2  A: 

I guess you need a master list or set of objects, either held by value if you can afford to copy them, or more likely held by pointer so you can copy the pointer and put them into other collections.

std::list<Foo*> Master;

These other collections (map1 and map2 in your example) can have these pointers inserted and removed at any time. When finally you want to delete everything, you can probably just delete the maps, or let them go out of scope, or ignore them, and just once, go back to the master list and iterate through that deleting the pointers that are found.

quamrana