开发者

I have a map<string, vector<record>>, how to remove records from vector<record>?

开发者 https://www.devze.com 2023-02-17 12:15 出处:网络
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.

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 fault

Any 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()

0

精彩评论

暂无评论...
验证码 换一张
取 消