Sarien
Sarien

Reputation: 6982

What is the most concise way to clear a map and delete contents?

I have a std::list and a std::map that I would like to empty and call delete on all the pointers.

After reading this question I am using this for the std::list:

mylist.remove_if([](myThingy* thingy) -> bool { delete thingy; return true; });

Is there something similarly concise for std::map?

Note that I cannot use a range based for loop because it isn't supported by my compiler (VC10). If it would be possible I assume

for(auto* thingy : myMap) { delete thingy; }
myMap.clear();

would work. Please correct me if I am wrong.

Upvotes: 1

Views: 7770

Answers (2)

James Kanze
James Kanze

Reputation: 153929

I don't think your remove_if solution is a good idea for the other types, either. Just use a simple loop (or foreach):

for ( auto current = myMap.begin(); current != myMap.end(); ++ current ) {
    delete current->second;
}
myMap.clear();

Note that you cannot do a delete current->first; this will invalidate keys in the map. And unless you are doing a clear() immediately afterwards (or are destructing the map), set the deleted pointer to NULL.

With regards to your second question:

for ( auto* thingy : myMap )

would certainly not work. The value type of map is a pair, not a pointer, so you'ld need somthing like:

for ( auto thingy : myMap ) { delete thingy.second; }

(I think. I've not been able to experiment with this either.)

Upvotes: 3

Andy Prowl
Andy Prowl

Reputation: 126452

Is there something similarly concise for std::map?

You could do it this way (supposing your thingy is the mapped value, and not the key):

for_each(myMap.begin(), myMap.end(), 
    [] (decltype(myMap)::value_type const& p) { delete p.second; });

myMap.clear();

Concerning the range-based for loop:

If it would be possible I assume

for(auto* thingy : myMap) { delete thingy; }
myMap.clear();

would work. Please correct me if I am wrong.

More or less. You still need to keep in mind that values of a map are actually pairs - but you could fix the range-based for to keep that into account, yes:

for (auto&& p : myMap) { delete p.second; }
myMap.clear();

Anyway, please consider using smart pointers instead of performing manual memory management through raw pointers, new, and delete. This way you would avoid this kind of problems.

Upvotes: 3

Related Questions