xdavidliu
xdavidliu

Reputation: 3042

inconsistent behavior with erasing map iterators in C++

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

Answers (3)

Slava
Slava

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

Zac Howland
Zac Howland

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

Johan
Johan

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

Related Questions