在STL中,对于容器vector,deque,如果执行了插入或者删除操作之后,之前的迭代器都失效了。
用例子来说明情况。
我们先构造一个vector:
vector<int> v;
int i = 0;
for (i=1;i<6;i++)
{
v.push_back(i);
}
for (i=5;i>0;i--)
{
v.push_back(i);
}
cout<<"Initial contents of v: \n";
for (i=0;i<v.size();i++)
{
cout<<v[i]<<" ";
}
cout<<"\n\n";
这时要求删除vector中的元素值为4的那两个元素
//定义一个迭代器,指向值为4的元素
vector<int>::iterator iter = v.begin() + 3;
cout<<"value of iter: "<<*iter<<"\n";
for (i = 0;i<v.size();i++)
{
if (*iter == v[i])
{
v.erase(iter);//vector iterator not dereferencable
}
}
当i=3时,遇到了第一个值为4的元素,此时调用了erase函数来删除此元素,正常执行;i=4时,执行*iter == v[i]时,就会报错,错误说明就是:vector iterator not dereferencable,这表明之前定义的iter迭代器失效了,再使用iter就会遇到这个问题,原因就是erase删除元素后,导致的iter迭代器失效。
所以当迭代器失效后,就要重新给迭代器赋值。
例如,修改之前代码中的内容:
//定义一个迭代器,指向值为4的元素
vector<int>::iterator iter = v.begin() + 3;
cout<<"value of iter: "<<*iter<<"\n";
for (i = 0;i<v.size();i++)
{
if (*iter == v[i])
{
int n = v[i];
v.erase(iter);
//查找vector中值为4的元素,返回迭代器指向此元素
iter = find(v.begin(),v.end(),n);
if (iter == v.end())
{
break;
}
}
}
这里我们以下语句实现通过重新查找vector内是否还有值为4的元素,如果有就返回指向此元素的迭代器,如果没有就返回end(),重新给iter赋新的迭代器
iter = find(v.begin(),v.end(),n);
最后在输出vector内容:
cout<<"after erase(), contents of v: \n";
for (i=0;i<v.size();i++)
{
cout<<v[i]<<" ";
}
cout<<"\n\n";
如预期一样删掉了vector中的值为4的元素,而且也没有迭代器失效的问题。
总结:在使用迭代器时,要特别注意当删除或者插入操作之后,迭代器的有效性问题,STL中没有对于迭代器有效性的检查功能。