Reputation:
I have a multimap with Note objects from which I want to remove only one object. There can be several Note objects with the same key. The problem is that right now there's also objects being removed that aren't within the key range I specify:
long key = note.measureNumber * 1000000 + note.startTime; // = 2000001
multimap<long, Note>::iterator it;
for (it = noteList.lower_bound(key); it != noteList.end() && it->first < (key + 1); it++) {
if(it->second.frequency == note.frequency){
noteList.erase(it);
}
}
When I run this code with key 2000001
the object I'm able to erase the right object, but another object with key 1000017
gets erased as well. Both objects have the same frequency though.
Any idea's what is wrong with my for loop?
EDIT: To be clear, I only want to check for objects with one specific key (in this case 2000001
) there's no need for the iterator to look at objects with different keys than that one.
Upvotes: 4
Views: 3729
Reputation: 1
As already indicated here, erasing an iterator invalidates it. I'd like to point out some inefficiency in code you have: You don't need to iterate till the end of the loop. Consider this:
for (it = noteList.lower_bound(key); it != noteList.upper_bound(key) && it->first == key; it++)
{
if(it->second.frequency == note.frequency)
{
noteList.erase(it++);
}
else
{
++it;
}
}
Upvotes: 0
Reputation: 7989
Once you erase an iterator it becomes invalid. If you wish to erase from a map while you iterate through it, your code needs to change. Try this:
multimap<long, Note>::iterator it;
for (it = noteList.lower_bound(key); it != noteList.end() && it->first < (key + 1);) {
if(it->second.frequency == note.frequency){
noteList.erase(it++);
}
else
{
++it;
}
}
Upvotes: 1
Reputation: 47462
Calling erase() with the iterator will invalidate it, so you can't then continue to use it.
See Can I continue to use an iterator after an item has been deleted from std::multimap<>
Upvotes: 2