Reputation: 3042
I'm very confused by the behavior of the erase function for maps. In the simple example below, the code outputs "224". However, if you comment out the line "m['e'] = 5", it outputs "221". Neither result makes sense to me. Can someone explain the logic here?
#include <iostream>
#include <map>
using namespace std;
int main(){
map<char, int> m;
m['a'] = 1;
m['b'] = 2;
m['c'] = 3;
m['d'] = 4;
m['e'] = 5;
map<char, int>::iterator it = m.begin(); it++;
cout << it->second;
m.erase(it);
cout << it->second;
it++;
cout << it->second << endl;
}
Upvotes: 0
Views: 118
Reputation: 44258
To erase elements in map for pre c++11 you can use this pattern:
for( map_type::iterator it = map.begin(); it != map.end(); ) {
if( condition_to_erease ) map.erase( it++ );
else ++i;
}
Why map.erase( it++ );
works? Because it is basically equivalent to this code:
map::iterator tmp = it;
++it;
map.erase( tmp );
You should understand semantics of postfics/prefics operators if you want to use C++ effectively.
For c++11 you can also use this:
for( auto it = map.begin(); it != map.end(); ) {
if( condition_to_erease ) it = map.erase( it );
else ++i;
}
I think in Visual C++ std::map::erase()
also returned iterator, but that was not in standard.
Upvotes: 0
Reputation: 15872
map<char, int>::iterator it = m.begin(); it++;
cout << it->second;
m.erase(it); // (1)
cout << it->second; // (2)
it++; // (3)
cout << it->second << endl;
You have invalidated the iterator at position (1)
, so attempting to dereference it in (2)
and (3)
is undefined behavior. It is virtually identical to deleting a pointer and then then attempting to dereference it.
Upvotes: 0
Reputation: 3778
You cannot use an iterator after erasing it. It is invalid and the behaviour is not determined (crash, wriong value ?):
http://en.cppreference.com/w/cpp/container/map/erase
Upvotes: 3