简体   繁体   中英

C++ Vector.erase() causing segmentation fault

I have a C++ vector and it has some blank elements in it. I wanted to remove any empty string elements from the vector. I tried this code:

for (i = 0; i < myvector.size();i++) {
  if (myvector[i] == "") {
    myvector.erase(myvector.begin()+i);
  }
}

When I run this code I get a segmentation fault. Is there something wrong with it? Or does this code work for any of you?

It appears that you want the usual remove-erase idiom:

#include <algorithm>
#include <functional>

myvector.erase(std::remove_if(myvector.begin(), myvector.end(),
                              std::mem_fn(&std::string::empty)),
               myvector.end());

If you have for example vec=["A","","B","C"] and you're delete the element a[1], now 'vec' is long 3 not 4, so vec[3] causes segmentation fault.

Try this:

for (vector<...>::iterator i=myvector.begin(); 
              i != myvector.end(); /* do nothing here */) {
   if (i->empty()) {
      i=myvector.erase(i);
   } else {
     ++i;
   }
}

However Kerrek's solution is more elegant.

First of all, I'm sorry for my English (I'm Brazilian and I'm using the Google translator). But your problem is not exclusively about deleting an item outside the vector, but about accessing its element. Think about the following situation: I have a vector v = {1, 4, 2} and I want to exclude all even numbers using a for and an iterator. When the iterator arrives at the second element (v [2]) it will exclude 4, making the vector {1,2}. But before leaving the for loop, the iterator is still pointing to the second element (v [2]), which is the last element. When it exits, the iterator will be incremented (i ++) and will be equal to v.end (). Therefore, even if it does not give a segmentation fault, the algorithm will not remove all even numbers and, if v was equal to {1,3,4}, it would give the segmentation fault. To fix this, right when you use v.erase (), use i-- (which in the case of your code, which does not directly use the iterator, will work in the same way).Or you can use an increment condition, as in the previous answer, but the iterator needs to be updated correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM