std::vector<int>v{ 0, 1, 2, 3 };
for (auto i = v.begin(); i != v.end(); i++)
{
cout << *i << endl;
v.erase(i);
cout << *i << endl; //报错的地方
}
这段代码在VS2013上运行会在第二处cout处报错,如下:
根据错误提示,迭代器不能被解引用,也就是说这里不能使用“*i”?那么为什么第一处*i不会报错,而第二处就会报错呢?这是迭代器失效导致的,那么为什么迭代器会失效呢?
都说迭代器失效的办法就是用erase的返回值来更新i,但是我看了一下SGI STL中erase的源码:
iterator erase(iterator __position) {
if (__position + 1 != end())
copy(__position + 1, _M_finish, __position);
--_M_finish;
destroy(_M_finish);
return __position;
}
整个过程也没有修改过position啊,只是把后面的数据拷贝到前面来了,并没有涉及到内存的重新分配(VS STL中源码也是类似的做法)我还把erase的返回值和实参进行比较,也都完全相同,为什么用erase的返回值更新迭代器就有用,不更新迭代器就失效了呢?
看了好几篇文章,似乎都把迭代器失效看作一个规定,也没有解释具体原因。那么失效的具体原因又是什么呢?
i = v.erase(i);
来更新迭代器,即使这样使用,也要先判断它是不是等于v.end()
, 才能决定能不能对其进行解引用