STL 中 使用迭代器删除元素的问题

在vector中删除,大家都知道,直接erase的话,这种写法很有问题。因为erase(iter)之后iter指针就变成野指针了,此时继续iter++就会出问题。

1 for(auto iter = v.begin(), iter!=v.end(); iter++)
2 {
3     if(iter == 3)
4     v.erase(iter);
5 }

 

因此vector中正确的删除的方法是:

 for(auto iter = v.begin(), iter!=v.end(); /*iter++*/)
 {
      if(iter == 3)
           iter = v.erase(iter);
       else
           iter++;
 }

 

但是在map中,正确的删除方法是:

for(auto iter1 = theMap.begin(); iter1 != theMap.end(); )  
{  
    if(iter1->second == xxx)  
    {  
        theMap.erase(iter1++);  
    }  
    else  
    {  
        ++iter1;  
    }  
}

因为对于map这种以指针构建起来的容器来说,可以保证一个元素删除了,不影响指向其它元素的迭代器。

 

总结:(转自:http://blog.csdn.net/hellokandy/article/details/52327549)

STL中的容器按存储方式分为两类:一类是序列容器(如:vector,deque),另一类是关联容器(如:list,map,set)。

在使用erase方法删除元素时,有几点需要注意:

1) 对于关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。

2)对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。还好erase方法可以返回下一个有效的iterator。

3)对于list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的iterator,因此上面两种正确的方法都可以使用。

posted @ 2017-09-22 10:45  mengmee  阅读(5824)  评论(0编辑  收藏  举报