I have tried all possibilities I could, and failed to find solution. Please help
I want to remove records in vector in map while iterating over it.
map < string, vector < record> >::iterator map_it;
for(map_it = map_records.begin(); map_it != map_records.end(); ++map_it){
vector < record>::iterator vec_it;
for(vec_it = (*map_it).second.begin(); vec_it != (*map_it).second.end();){
if(condition){
cout << (*map_it).second.size() << endl;
vec_it 开发者_运维技巧= map_it->second.erase(vec_it);
cout << (*map_it).second.size()<< endl;
} else {
++vec_it;
}
}
}
I tried something like this,
(*map_it).second.erase(vec_it)
It give some long number if I query the size of it and program ends with segmentation fault
OUTPUT:
18446744073709551615 18446744073709551615 Segmentation faultAny help appreciated
vec_t = map_it->second.erase(vec_it); //note the assignment!
You also need to check it's validity immediately, so better re-write the inner loop as:
for(vec_it = (*map_it).second.begin(); vec_it != (*map_it).second.end(); )
{
if(condition)
vec_it = map_it->second.erase(vec_it);
else
++vec_it;
}
You are invalidating your iterator. If you are going to erase objects from your vector while iterating over it, you should be sure to take the return value of erase (which is the iterator of the next object, or vector::end) and set the iterator to that, otherwise it will become invalid and your program will probably crash.
if(condition){
vec_it = map_it->second.erase(vec_it);
}
//added for completeness
//if the for loop has a ++vec_it, we should break before
//it gets to do it on an end iterator
if(vec_it == map_it->second.end()) {
break;
}
Instead of using conditional erases on a vector, rather use the std::remove_if
. and then erase
idiom. It will be quicker because it will not move all elements of your vector multiple times.
In the conditional, you can do this:
vec_it = (*map_it).second.erase( vec_it );
And it'll erase the item in the map at that iterator position.
More Info on C++ Vector::Erase()
精彩评论