遍历一个容器同时删除这个容器的迭代器,会使这个容器失效
来看下什么是迭代器, 任何特定的迭代器都是某个类型的对象,vectorr的迭代器可以被实现为一个到vector的指针,加一个下标
表的迭代器可以是一个指向链表的指针, 所有迭代器的共同之处在于它们的语义,以及它们的有关操作的名字。
eg.迭代器++操作总是产生引用下一个元素的迭代器, *总是产生这个迭代器引用的那个元素,基本上符合这些的都可以成为迭代器了
常用的遍历删除迭代器方法,拿map举例
map<int, int> mp;
for( int i = 0; i < 10; ++i )
{
mp[i] = i;
}
map<int, int>::iterator iter = mp.begin();
while( iter != mp.end() )
{
if ( iter->first < 10 )
{
mp.erase( iter++ );
}
else
{
++iter;
}
}
在删除时记录下下一个有效的迭代器就OK了
如果用同样的方法使用在vector上就崩了,这个是为什么呢
vector<int> vec;
for( int i = 0 ;i < 20; ++i )
{
vec.push_back( i );
}
vector<int>::iterator it = vec.begin();
while( it != vec.end() )
{
if ( *it < 10 )
{
vec.erase( it++ ); // 导致崩溃
}
else
{
++it;
}
}
这是因为vector和list,map删除迭代器后结果不一样, 因为map, list删除迭代器后,只有当前删除的迭代器无效, it++就可以获得下一个有效的迭代器了,但是vector 删除迭代器后,
当前删除的迭代器之后的所有迭代器都会失效
正确方法
#include <windows.h>
#include <map>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
bool gt_val( int val )
{
return val%2 == 0 ? true : false;
}
int main()
{
vector<int> vec;
for( int i = 0 ;i < 20; ++i )
{
vec.push_back( i );
}
// 标准库调用方法
vector<int>::iterator it = vec.begin();
while( (it = find_if( it, vec.end(), gt_val))!= vec.end() )
{
it = vec.erase( it );
}
// 普通调用方法
it = vec.begin();
while( it != vec.end() )
{
if ( *it < 10 )
{
it = vec.erase( it );
}
else
{
++it;
}
}
map<int, int> mp;
for( int i = 0; i < 10; ++i )
{
mp[i] = i;
}
map<int, int>::iterator iter = mp.begin();
while( iter != mp.end() )
{
if ( iter->first < 10 )
{
iter = mp.erase( iter );
}
else
{
++iter;
}
}
}
posted on 2011-11-08 17:33
风轻云淡 阅读(686)
评论(0) 编辑 收藏 引用 所属分类:
C++