擦除元素时std :: vector中可能存在的不一致

mah*_*ood 2 c++ vector

在调试向量时,我发现不一致.假设以下代码尝试从只有一个元素的向量中删除一个条目

#include <iostream>
#include <vector>
std::vector<int> v;
void myremove(int);
int main()
{
  v.push_back(10); 
  std::cout << "10 pushed back\n";
  myremove(10);
  std::cout << "done :)\n";
  return 0;
}

void myremove( int a )
{
  std::vector<int>::iterator it = v.begin();
  int counter = 0;
  for ( ; it != v.end(); it++ ) {
    std::cout << "iterating for " << counter << " times and vector size is " << v.size() << "\n";
    if ( a == (*it) ) {
      v.erase(it);
      std::cout << "removed " << a << "\n";
    }
    ++counter; 
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我在输出中看到的:

 $ g++ test.cpp 
 $ ./a.out | more
 10 pushed back
 iterating for 0 times and vector size is 1
 removed 10
 iterating for 1 times and vector size is 0
 iterating for 2 times and vector size is 0
 iterating for 3 times and vector size is 0
 iterating for 4 times and vector size is 0
 iterating for 5 times and vector size is 0
 iterating for 6 times and vector size is 0
 ....
 ....
 iterating for 33790 times and vector size is 0
 Segmentation fault
Run Code Online (Sandbox Code Playgroud)

我理解的是,当元素被移除时,大小将变为0,但迭代器移动一步仍然尝试到达结束但他不知道他已经通过了终点.

有人可以解释更多正在发生的事情以及如何避免这种情况吗?

hmj*_*mjd 6

erase()对迭代器的调用it失效后:

对迭代元素及其与容器末尾之间的元素的迭代器和引用无效.

设置iterase()相反的返回值,如果没有发生删除,则仅增加:

while (it != v.end())
{
    if ( a == (*it) )
    {
        it = v.erase(it);
        std::cout << "removed " << a << "\n";
    }
    else
    {
        ++it;
    }
}
Run Code Online (Sandbox Code Playgroud)

其中返回值为erase():

最后一个删除元素后面的迭代器.

您可以使用std::remove_if()而不是手动编码循环来擦除元素:

v.erase(std::remove_if(v.begin(),
                       v.end(),
                       [](const int i) { return i == 10; }),
        v.end());
Run Code Online (Sandbox Code Playgroud)