使用过STL的人都应该知道关于迭代器失效的原理,这里以后vector迭代器失效为例:
第一种:当插入一个元素到vector中,如果插入后容器已满,那么容器将新开辟一块内存区域,然后
将原内存中的数据拷贝到新的内存区域,同时释放旧的内存。这样之前指向旧内存的迭代器就会指向
不确定内存,这块内存要么释放,要么释放后又用作其他用途。这便导致了迭代器失效。
第二种:当删除容器中一个元素后,该迭代器所指向的元素已经被删除,那么也造成迭代器失效。
这里我们主要讨论下第二种情况。
我们先举个例子说明:
比如vector中存储了1,2,3,4,5,6,7,8,9,10
假如此时迭代器指向6.
当我们erase这个迭代器的元素后,vecotr被删除元素后面的元素会依次前移动。
变为1,2,3,4,5,7,8,9,10 此时迭代器指向元素7 也就是被删除元素的下一个元素。
所以当我们用以下测试代码测试的时候,发现会出现错误:
#include <iostream>
#include <vector>
using namespace std; int main(int argc, char* argv[])
{
std::vector<int> v1;
for(int i = ;i <= ;i++)
{
v1.push_back(i);
} for(vector<int>::iterator it = v1.begin();it != v1.end();)
{
if(*it==)
{
v1.erase(it);
}
else
{
it++;
}
} for(it = v1.begin();it != v1.end();it++)
{
cout<<*it<<",";
}
cout<<endl;
return ;
}
因为删除元素的所指的迭代器已经失效
但是由于erase方法会返回下一个有效的迭代器。所以
我们再每次删除后让迭代器重新被erase返回即可。
所以修改后的代码如下:
#include <iostream>
#include <vector>
using namespace std; int main(int argc, char* argv[])
{
std::vector<int> v1;
for(int i = ;i <= ;i++)
{
v1.push_back(i);
} for(vector<int>::iterator it = v1.begin();it != v1.end();)
{
if(*it==)
{
it=v1.erase(it);
}
else
{
it++;
}
} for(it = v1.begin();it != v1.end();it++)
{
cout<<*it<<",";
}
cout<<endl;
return ;
}
运行结果: