有关stl容器删除元素的问题,错误的代码如下:

  1. std::vector<struct> mFriendList;
  2. ...
  3. std::vector<struct>::iterator iter = mFriendList.begin();
  4. for ( ; iter != mFriendList.end(); ++iter)
  5. {
  6. if (...)
  7. mFriendList.erase(iter);
  8. }

记得当时Once给我说过这个问题,还给我改过代码,我当时不明白为什么,只知道程序执行的时候如果if为true那么程序就肯定会崩溃。
大师的说法是:当容易中的一个元素被删除时,指向该元素的所有迭代器都变得无效。上面的代码中,只要执行了erase(iter),那么iter就会变得无效,那么执行++iter就肯定会出错。

在网上看到有人总结如下两条:
1. 对于节点式容器(map, list, set)元素的删除,插入操作会导致指向该元素的迭代器失效,其他元素迭代器不受影响
2. 对于顺序式容器(vector,string,deque)元素的删除、插入操作会导致指向该元素以及后面的元素的迭代器失效

总结了一下,并回想Once当时给我改的代码,所以正确的写法应该是这样的:

1.

  1. #include <iostream>
  2. #include <list>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <iterator>
  6.  
  7. using namespace std;
  8.  
  9. int main(int argc, char* argv[])
  10. {
  11. vector<int> MyList;
  12.  
  13. for (int i = ; i < ; i++)
  14. {
  15. MyList.push_back(i);
  16. }
  17.  
  18. vector<int>::iterator Itor = MyList.begin();
  19.  
  20. for (;Itor != MyList.end();)
  21. {
  22. if ( *Itor == )
  23. {
  24. Itor = MyList.erase(Itor);
  25. }
  26. else
  27. {
  28. Itor++;
  29. }
  30. }
  31.  
  32. copy(MyList.begin(), MyList.end(), ostream_iterator<int>(cout, " ") );
  33. cout<<endl;
  34.  
  35. return ;
  36. }

2.对于节点式容器

  1. //下面其它的总结, 写法有点怪
    std::list<struct> mList;
  2. ...
  3. std::list<struct>::iterator iter = mList.begin();
  4. for ( ; iter != mList.end(); )
  5. {
  6. if (...)
  7. {
  8. //因为节点式只会导致当前节点迭代器失效,所以删除节点的同时对迭代器进行后移的操作,因为其他元素不会失效
  9. mList.erase(iter++);
  10. }
  11. else
  12. {
  13. ++iter;
  14. }
  15. }

3.对于顺序式容器

  1. std::vector<struct> mVector;
  2. ...
  3. std::vector<struct>::iterator iter = mVector.begin();
  4. for ( ; iter != mVector.end(); )
  5. {
  6. if (...)
  7. {
  8. //这里就比较有说法了,因为顺序式容器会使本身和后面的元素迭代器都失效,所以不能简单的++操作
  9. //这里顺序式容器的erase()会返回紧随被删除元素的下一个元素的有效迭代器
  10. //而节点式容器的erase()的返回值是void,这点我感觉太神奇了,确实太神奇了!!!!
  11. iter = mVector.erase(iter);
  12. }
  13. else
  14. {
  15. ++iter;
  16. }
  17. }

注意:容器看具体STL库的实现了,VS中两类容器的earse都返回下一个迭代器指针。

删除STL容器中的元素的更多相关文章

  1. 删除 list 集合中的元素

    删除 list 集合中的元素,当删除的元素有多个的时候,只能使用迭代器来删除. 当删除 list 集合中的元素只有一个的时候,有三种方法都可以实现. import java.util.ArrayLis ...

  2. 怎么删除STL容器的元素

    在STL容器有顺序容器和关联容器两种. 顺序容器删除元素的方法有两种: 1.c.erase(p) 从c中删除迭代器p指定的元素.p必须指向c中一个真实元素,不能等于c.end().返回一个指向p之后元 ...

  3. [Flex] Accordion系列-动态添加或删除Accordion容器中项目

    <?xml version="1.0" encoding="utf-8"?> <!--Flex中如何使用addChild()和removeCh ...

  4. c++随机排序容器中的元素

    在各种程序语言中都提供了将容器元素随机排序的shuffle方法,c++也不例外. 不过c++将shuffle放在了<algorithm>中而不是像其他语言一样在random里,同时c++1 ...

  5. 定时脚本删除docker容器中内容

    今天在我同步mongo数据库的时候,服务器的磁盘突然就被占满了导致同步中断,mongo容器也停止工作了.然后就想要弄一个能够定时清理同步过程中留存在docker容器中的mongo数据的脚本.话不多说, ...

  6. 删除JavaScript对象中的元素

    参考http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object 通过dojo ...

  7. 删除map容器中指定的元素

    for (std::map<Int64,Int64>::iterator iter = ips_forbidden_.begin(); iter != ips_forbidden_.end ...

  8. 如何删除PHP数组中的元素,并且索引重排(unset,array_splice)?

    如果要在某个数组中删除一个元素,可以直接用的unset,但是数组的索引不会重排: <?php $arr = array('a','b','c','d'); unset($arr[1]); pri ...

  9. 如何删除JAVA集合中的元素

    经常我们要删除集合中的某些元素.有些可能会这么写. public void operate(List list){ for (Iterator it = list.iterator(); it.has ...

随机推荐

  1. Codeforces Round #574 (Div. 2) A~E Solution

    A. Drinks Choosing 有 $n$ 个人,每个人各有一种最喜欢的饮料,但是买饮料的时候只能同一种的两个两个买(两个一对) 学校只打算卖 $\left \lceil \frac{n}{2} ...

  2. 在vue中运用mt-loadmore 实现上拉加载,下拉刷新(完整源码)

    <template> <div class="serverList"> <ul class="scrollModeBox" :st ...

  3. 重命名sql数据库

    use master select spid from master.dbo.sysprocesses where dbid=db_id('TW') 查看连接,杀死线程 use master kill ...

  4. C语言字符串复制

    strcpy(arg1,arg2);//将arg2内容赋值到arg1 strncpy(arg1,arg2,size);//赋值多少由size决定,如果要截取某一部分,可以将arg2指针进行arg2+x ...

  5. shell脚本实现ftp上传下载文件

    前段时间工作中需要将经过我司平台某些信息核验数据提取后上传到客户的FTP服务器上,以便于他们进行相关的信息比对核验.由于包含这些信息的主机只有4台,采取的策略是将生成的4个文件汇集到一个主机上,然后在 ...

  6. 【python实例】判断是否是回文数

    """ 输入一个数,判断一个这个数是否是回文数.例如:121,这个数反过来还是121,所以这个是回文数: 再如:134,这个数反过来是431,所以这不是一个回文数: 12 ...

  7. java23种设计模式(三)-- 适配器模式

    一.适配器模式 转载:https://www.cnblogs.com/V1haoge/p/6479118.html 适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配, ...

  8. ubuntu 彻底删除软件

    无法获取 dpkg 前端锁 解决办法如下:1.终端输入 ps  aux ,列出进程.找到含有apt-get的进程,直接sudo kill PID. 2.强制解锁,命令sudo rm /var/cach ...

  9. spark的知识的链接

    IDEA 创建scala spark的Mvn项目:https://blog.csdn.net/u014646662/article/details/84618032 Spark详解03Job 物理执行 ...

  10. SpringBoot---提供的自动配置

    1.自动配置的ViewResolver 1.1.ContentNegotiatingViewResolver 1.2.BeanNameViewResolver 1.3.InternalResource ...