Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erasing while traversing in C++ stl map giving runtime error

Following lines of C++ code gives runtime error but if erase operation mymap.erase(v) is removed it works:

map<int,int> mymap = {{1,0},{2,1},{9,2},{10,3},{11,4}};
for(auto it=mymap.rbegin();it!=mymap.rend();){
    int v=it->first;
    ++it;
    mymap.erase(v);
}

demo

Here iterator it is changed before deleting its value v, so iterator it should remain unaffected I believe.

like image 402
Pratap Singh Avatar asked May 19 '21 22:05

Pratap Singh


1 Answers

When you are calling erase(v), you are invalidating the base iterator that the next reverse_iterator (from ++it) is using. So you need to create a new reverse_iterator from the base iterator that precedes the erased value.

Also, rather than erasing the value that the reverse_iterator is referring to, you should erase the base iterator instead, since you already know which element you want to erase. There is no need to make the map go hunting for the value again.

This works for me:

map<int,int> mymap = {{1,0},{2,1},{9,2},{10,3},{11,4}};
for(auto it = mymap.rbegin(); it != mymap.rend(); ){
    auto v = --(it.base());
    v = mymap.erase(v);
    it = map<int,int>::reverse_iterator(v);
}

Demo

On the other hand, this loop is essentially just erase()'ing all elements from mymap, so a better option is to use mymap.clear() instead.

like image 186
Remy Lebeau Avatar answered Sep 27 '22 19:09

Remy Lebeau