// erasing from map
#include <iostream>
#include <map>
using namespace std;
int main ()
{
map<char,int> mymap;
map<char,int>::iterator it(mymap.begin());
// insert some values:
mymap['a']=10;
mymap['b']=20;
mymap['c']=30;
mymap['d']=40;
mymap['e']=50;
mymap['f']=60;
it=mymap.find('a');
mymap.erase (it); // erasing by iterator
// show content:
for (; it != mymap.end(); it++ )
cout << (*it).first << " => " << (*it).second << endl;
return 0;
}
Why does this give an output like
a => 10
b => 20
c => 30
d => 40
e => 50
f => 60
shouldn't "a => 10"
be deleted anyways, but if I declare it = mymap.begin()
in the for loop, everything is perfect. why?
program adapted from : http://www.cplusplus.com/reference/stl/map/erase/
Every iterator and reference after the point of erasing is invalidated. Only the iterators and references to the erased element is invalidated. Only iterators and references to the erased elements are invalidated.
map::clear() function is an inbuilt function in C++ STL, which is defined in header file. clear() is used to remove all the content from the associated map container. This function removes all the values and makes the size of the container as 0.
Inserting into std::map does not invalidate existing iterators.
map() loops over the items of an input iterable (or iterables) and returns an iterator that results from applying a transformation function to every item in the original input iterable.
Erasing an element of a map
invalidates iterators pointing to that element (after all that element has been deleted). You shouldn't reuse that iterator.
Since C++11 erase()
returns a new iterator pointing to the next element, which can be used to continue iterating:
it = mymap.begin();
while (it != mymap.end()) {
if (something)
it = mymap.erase(it);
else
it++;
}
Before C++11 you would have to manually advance the iterator to the next element before the deletion takes place, for example like this:
mymap.erase(it++);
This works because the post-increment side-effect of it++
happens before erase()
deletes the element. Since this is maybe not immediately obvious, the C++11 variant above should be preferred.
Calling erase()
invalidates the iterator. In this case, what's happening is the iterator points to the residual value left behind in memory (but don't rely on this undefined behaviour!). Reset the iterator with it=mymap.begin()
before the loop for the desired results.
http://codepad.org/zVFRtoV5
This answer shows how to erase elements while iterating over an std::map
:
for(map<T, S*>::iterator it = T2pS.begin(); it != T2pS.end(); T2pS.erase(it++)) {
// wilhelmtell in the comments is right: no need to check for NULL.
// delete of a NULL pointer is a no-op.
if(it->second != NULL) {
delete it->second;
it->second = NULL;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With