在下面的代码中,我试图用erase删除vector中的所有值为偶数的元素。根据c++primer 11,erase的返回值是指向被删除元素之后元素的迭代器。根据我的想法,我认为既然是删除一个元素,那么该被删除元素之后的所有元素都会往前移动一个位置,因此在删除该元素后,指向该被删除元素的迭代其器变成指向下一个元素的迭代器,但是却出现了错误。晚上的解答是使用erase(p)之后,p变为无效状态。
有问题的代码:
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main()
{
int a[] = { 0,1,1,2,3,5,8,13,21,55,89 };
vector<int> vi(begin(a), end(a));
//list<int> li(begin(a), end(a));
auto it1 = vi.begin();
while (it1 != vi.end())
{
if (*it1 % 2 == 0)
{
vi.erase(it1);
}
else
{
++it1;
}
}
for (auto v : vi) cout << v << " ";
return 0;
}
正确代码:
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main()
{
int a[] = { 0,1,1,2,3,5,8,13,21,55,89 };
vector<int> vi(begin(a), end(a));
//list<int> li(begin(a), end(a));
auto it1 = vi.begin();
while (it1 != vi.end())
{
if (*it1 % 2 == 0)
{
it1 = vi.erase(it1);
}
else
{
++it1;
}
}
for (auto v : vi) cout << v << " ";
return 0;
}
然而这个回答没有消除我的疑问,因为在单步调试时出现了下面的情况,似乎每一步都是合理的,指向被删除的元素的迭代器确实成为指向下一个元素的迭代器。
it1指向0元素,0将被删除

元素0被删除。 it1指向1。目前执行到if语句。再往下执行一步(也就是执行该if语句)就报错了,但是此时it1确实是有效的,让人十分费解。。。有空在琢磨一下吧,在此记录一下这个问题。

---------------------------------------------------------------------------------------------------------------------------------
最近在知乎上看到了一条答案:在debug模式下使用失效的迭代器会报错,在realease下不会报错,但可能造成更加严重的后果。
博客探讨了在C++中使用`std::vector::erase`删除元素后,迭代器失效的问题。作者遇到的错误是尝试在删除元素后继续使用已失效的迭代器。正确的做法是使用`erase`的返回值更新迭代器。调试时在Debug模式下会立即捕获错误,而在Release模式下可能会导致更严重的后果。解决方案是确保在删除元素后立即更新迭代器。
1026

被折叠的 条评论
为什么被折叠?



