Reputation: 5110
I had to delete some of the entries from c++ std::map
, for that purpose I iterate over the std::map
and used erase. But I get an error. The error is like :
0x0017f3f6 in std::_Rb_tree_rebalance_for_erase () from /usr/local/lib/libstdc++.so.6
(gdb) bt
#0 0x0017f3f6 in std::_Rb_tree_rebalance_for_erase () from /usr/local/lib/libstdc++.so.6
#1 0x00487ef4 in getLetters () from /usr/lib/libmail.so
#2 0x0048cacc in getHeader () from /usr/lib/libmail.so
#6 0x08048802 in __gxx_personality_v0 ()
#7 0x00251e9c in __libc_start_main () from /lib/libc.so.6
#8 0x080486a1 in __gxx_personality_v0 ()
(gdb)
The code was something like this:
int nlsize=LettersMap.size();
if(nlsize > MAXNL)
{
std::map <std::string,MSG_HEADER>::iterator it;
int i=0;
for( i=0, it=LettersMap.begin(); i <nlsize-MAXNL ;i++, it++)
{
LettersMap.erase(it);
}
}
Can someone please point out the error
Upvotes: 1
Views: 2456
Reputation: 4217
You have an iterator
to the std::map
, right? In your for
loop, you initialize your iterator
to the beginning. You check if it is within bounds. You then erase
the iterator
. Your iterator
is now invalid. The iterator
s are effectively like pointers and when you erase
, you are effectively delete
ing a value that was "pointed" to. As such, other iterator
s can't guarantee that they point to something valid.
Specifically, you erase
, causing an invalidation of your iterator
. A guaranteed one, because it's the iterator
you erase
d. You need a new iterator
, preferably one right after where you erase
d, right? Unfortunately, std::map
does not offer that functionality. std::map
isn't really intended to be treated as a sequential container. The idea is that you access values by their key, not their position. Seeing as you're trying to erase by their sequential order, this is problematic.
Instead, perhaps, you could identify which key you need to erase based on i
? Then use find
to find the key and erase
to erase the key. Since you are no longer sequentially iterating through your std::map
, you no longer have to worry about invalidated iterator
s.
Upvotes: 3
Reputation: 109547
int n = nlsize - MAXNL;
while (n-- > 0) {
LettersMap.erase(LettersMap.begin());
}
The iterator it
is becoming instable by erase
.
Upvotes: 2