vector和map的迭代器失效问题

时间:2022-03-10 04:17:09

1.vector

#include <iostream>
#include <string>
#include <vector>
using namespace std;
void vectorTest()
{
vector<int> container;
for (int i = 0; i < 10; i++)
{
container.push_back(i);
}

vector<int>::iterator iter;
for (iter = container.begin(); iter != container.end(); iter++)//循环2
{
container.erase(iter);
}

for (iter = container.begin(); iter != container.end(); iter++)
{
cout<<*iter<<endl;
}
}
int main(int argc, const char *argv[])
{
vectorTest();
return 0;
}

执行结果 : 0 1 2 3 5 7 9

在vector中删除一个元素时,后面的元素会前移一位,所以原来的迭代器都失效了

删除第一个比3大的数4后:0 1 2 3 5 6 7 8 9

--->但是此时迭代器指向5,然后iter++,又指向6了,把5漏掉。。。导致的是后面有5 7 9依然没删除

修改的方法:在循环2中:

     for (iter = container.begin(); iter != container.end();)
{
if(*iter > 3)
{
container.erase(iter);
continue;
}
iter++;
}

或者:

  for (iter = container.begin(); iter != container.end();)
{
if(*iter > 3)
{
iter = container.erase(iter);//此时的iter指向的位置没有变,只是此时指向的内容变成原来元素后面的一个了
continue;
}
iter++;
}


2.map的失效

map是关联容器,以红黑树或者平衡二叉树组织数据,虽然删除了一个元素,整棵树也会调整,以符合红黑树或者二叉树的规范,但是单个节点在内存中的地址没有变化,变化的是各节点之间的指向关系

http://blog.163.com/xychenbaihu@yeah/blog/static/1322296552010824114547940/

http://blog.csdn.net/v_july_v/article/details/6105630 有关于红黑树的删除,比较复杂


序列性容器::(vector和list和deque)
        erase迭代器不仅使所指向被删元素的迭代器失效,而且使被删元素之后的所有迭代器失效,所以不能使用erase(iter++)的方式,但是erase的返回值为下一个有效的迭代器。

        所以正确方法为::
        for( iter = c.begin(); iter != c.end(); )
              iter = c.erase(iter);
 
关联性容器::(map和set比较常用)
        erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器, 
        所以正确方法为::
        for( iter = c.begin(); iter != c.end(); ) 
              c.erase(iter++);

Tips:
       其实对于list两种方式都可以正常工作


STL的容器删除元素,除了使用迭代器外,还可以使用erase(key)的方式。
size_t rm_num = obj.erase(key);
rm_num标示删除key的成员的个数,在map中key是key值,在其他容器中,key是一个value。