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,因此上面两种正确的方法都可以使用。

时间: 2024-11-12 16:54:20

STL 中 使用迭代器删除元素的问题的相关文章

STL中慎重选择删除元素的方法

 一.要删除容器中有特定值的所有对象 1.如果容器是vector.string或deque,则使用erase-remove习惯用法.例如: vector<int> c; c.erase(remove(c.begin(),c.end(),1963),c.end());//删除值是1963的元素 下面讲一下算法remove: template<classForwardIterator,class T> ForwardIteratorremove(ForwardIterator fi

一步一步认识C++STL中的迭代器

一步一步认识C++STL中的迭代器 "指针"对所有C/C++的程序员来说,一点都不陌生.在接触到C语言中的malloc函数和C++中的new函数后,我们也知道这两个函数返回的都是一个指针,该指针指向我们所申请的一个"堆".提到"堆",就不得不想到"栈",从C/C++程序设计的角度思考,"堆"和"栈"最大的区别是"栈"由系统自动分配并且自动回收,而"堆&quo

JavaScript向select下拉框中添加和删除元素

JavaScript向select下拉框中添加和删除元素 1.说明 a   利用append()方法向下拉框中添加元素 b   利用remove()方法移除下拉框中最后一个元素 2.设计源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xm

STL容器遍历时删除元素

STL容器遍历时在循环体内删除元素最容易出错了,根本原因都是因为迭代器有效性问题,在此记下通用删除方法,该方法适用于所有容器: 1 std::vector<int> myvec; 2 3 std::vector<int>::iterator it = myvec.begin(); 4 while( it != myvec.end()) 5 { 6 it = myvec.erase(it); 7 } 容器list有个比较另类的删除方法,如下代码所示: std::list<int

vector容器中添加和删除元素

添加元素: 方法一: insert() 插入元素到Vector中 iterator insert( iterator loc, const TYPE &val ); //在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器 void insert( iterator loc, size_type num, const TYPE &val ); //在指定位置loc前插入num个值为val的元素 void insert( iterator loc, input_iterator

STL中,迭代器的分类

五类迭代器如下: 1.输入迭代器:只读,一次传递    为输入迭代器预定义实现只有istream_iterator和istreambuf_iterator,用于从一个输入流istream中读取.一个输入迭代器仅能对它所选择的每个元素进行一次解析,它们只能向前移动.一个专门的构造函数定义了超越末尾的值.总是,输入迭代器可以对读操作的结果进行解析(对每个值仅解析一次),然后向前移动.   2.输出迭代器:只写,一次传递    这是对输入迭代器的补充,不过是写操作而不是读操作.为输出迭代器的预定义实现

python中遍历list删除元素引发的问题与解决办法

引发问题的场景 今天在写一个小游戏的demo时,进行游戏元素操作时,遇到了一个问题.类似下面代码: list = ['a','b','c','d'] # element_type == list for i in list: print('元素的下标为{},元素的值{}'.format(list.index(i),list)) # 打出内容.方便查看 list.remove(i) print(list) 本意是遍历删除list中的所有元素.最后list应该为一个空数组. 但是代码实际运行结果是

STL中的迭代器的使用

package com.text; import java.lang.reflect.Field;import java.util.ArrayList;import java.util.Iterator;import java.util.ListIterator; public class text { public static void main(String[] args)throws Exception {      //定义一个arraylsit 对象,然后赋值  ArrayList

集合遍历过程iterator, 添加删除元素报异常

list  set  遍历过程中添加或者删除元素,报异常. 使用iterator 也会报异常 ConcurrentModificationException remove只能用迭代器的remove,而不能用集合的remove方法,iterator的remove会维护索引的一致性 iterator it = list.iterator(); while(it.hasnext(0){ obj = it.next(); it.remove(); } 用java.util.concurrent中的类代替