在调试向量时,我发现不一致.假设以下代码尝试从只有一个元素的向量中删除一个条目
#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,但迭代器移动一步仍然尝试到达结束但他不知道他已经通过了终点.
有人可以解释更多正在发生的事情以及如何避免这种情况吗?
erase()对迭代器的调用it失效后:
对迭代元素及其与容器末尾之间的元素的迭代器和引用无效.
设置it为erase()相反的返回值,如果没有发生删除,则仅增加:
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)