您的位置:首页 > 其它

vector和map的erase问题

2010-08-16 23:08 323 查看
STL map的不经意的小问题

// erasing from map
#include <iostream>
#include <map>
#include <iterator>
using namespace std;
int main ()
{

map<char,int> mymap;
map<char,int>::iterator it;
// insert some values:
mymap['a']=10;
mymap['b']=20;
mymap['c']=30;
mymap['d']=30;
mymap['e']=10;
mymap['f']=10;

// show content:

for ( it=mymap.begin() ; it != mymap.end();  it++)
{

cout << (*it).first << " => " << (*it).second << endl;

mymap.erase(it);

}

system("pause");
return 0;

}


这是工作中遇到的一个问题,由于对map理解的不深刻,导致bus error。乍一看,程序似乎没有问题,我们的for 循环一直是这么写的,但是仔细分析一下map删除的机制:原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用,否则会导致程序无定义的行为。这里it已经删除,已经是个野指针,不能再用it++
正确的操作是mymap.erase(it++);
mymap中在删除it的时候,先将it做缓存,然后执行it++使之指向下一个结点,再进入erase函数体中执行删除操作,删除时使用的it就是缓存下来的it(也就是当前it(做了加操作之后的it)所指向结点的上一个结点)。
当然vector不存在这种问题,但是看下面一个小程序:
vector<char> alphaVector;
for( int i=0; i < 10; i++ )
alphaVector.push_back( i + 65 );
int size = alphaVector.size();
vector<char>::iterator startIterator;
vector<char>::iterator tempIterator;
for( int i=0; i < size; i++ )
{
startIterator = alphaVector.begin();

alphaVector.erase( startIterator );
// Display the vector

for( tempIterator = alphaVector.begin(); tempIterator != alphaVector.end(); tempIterator++ )

cout << *tempIterator;

cout << endl;

}

这段代码将会显示如下输出:
BCDEFGHIJ

CDEFGHIJ

DEFGHIJ

EFGHIJ

FGHIJ

GHIJ

HIJ

IJ

J

如果for( int i=0; i < size; i++ )
改成for( it=alphaVector.begin(); it!= alphaVector.end(); it++ )
那得到的结果是
BCDEFGHIJ

CDEFGHIJ

DEFGHIJ

EFGHIJ

FGHIJ
这表明vector size是动态更新的。而且vector.erase(it) it指向删除的最后一个元素的下一位置的迭代器,而map.erase(it)不会!切记!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: