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

std::vector<struct> mFriendList;
...
std::vector<struct>::iterator iter = mFriendList.begin();
for ( ; iter != mFriendList.end(); ++iter)
{
if (...)
mFriendList.erase(iter);
}

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

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

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

1.

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <iterator> using namespace std; int main(int argc, char* argv[])
{
vector<int> MyList; for (int i = ; i < ; i++)
{
MyList.push_back(i);
} vector<int>::iterator Itor = MyList.begin(); for (;Itor != MyList.end();)
{
if ( *Itor == )
{
Itor = MyList.erase(Itor);
}
else
{
Itor++;
}
} copy(MyList.begin(), MyList.end(), ostream_iterator<int>(cout, " ") );
cout<<endl; return ;
}

2.对于节点式容器

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

3.对于顺序式容器

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

注意:容器看具体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. Robotframework使用自写库连接mysql数据库

    Robotframework使用自写库连接mysql数据库 新建库文件mysqltest.py 代码如下: # -*- coding: utf-8 -*- import MySQLdbimport o ...

  2. ssh公私钥免密登陆

    简介ssh Secure Shell(简写SSH) 为一项建立在应用层和传输层基础上的安全协议,专门为远程登录会话和其他网络服务提供安全性的协议. SSH安全机制分为两种,一种是基于口令的安全认证,一 ...

  3. Pytest+Allure2+Jenkins搭建

    前置: (1)安装Python3(这里版本为3.7) (2)搭建Jenkins环境 一.安装pytest 直接使用pip安装(这里由于笔者的环境同时安装了Python2和Python3,所以在pyth ...

  4. XML学习——java解析xml文件

    递归获取每个标签 package test; import java.io.File; import java.util.List; import org.dom4j.Document; import ...

  5. 2019牛客暑期多校训练营(第一场) - E - ABBA - 贪心 - dp - 组合

    https://ac.nowcoder.com/acm/contest/881/E 从dp的角度来看是比较正常的.无后效性来源于前面只要的合法的方案分配,那么对后面造成的影响就只有A,B的数目. 从贪 ...

  6. C# 使用Silverlight打印图片

    原文:https://www.cnblogs.com/jiajiayuan/archive/2012/04/13/2444246.html Silverlight中的打印只有一个类,那就是PrintD ...

  7. git如何删除远程仓库的某次错误提交

    git如何删除远程仓库的某次错误提交 如果远程仓库,能ssh访问,那就跟本地没什么区别   reset命令有3种方式   git reset --mixed 此为默认方式,不带任何参数的git res ...

  8. uoj396 [NOI2018]屠龙勇士

    [NOI2018]屠龙勇士 描述 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号 1∼n 顺序杀掉 n 条巨龙,每条巨龙拥有一个初始的生命值 ai .同时每条巨龙拥有恢复能 ...

  9. elasticsearch 深入 —— Top Hits Aggregation

    Top Hits Aggregation top_hits指标聚合器跟踪正在聚合的最相关文档. 此聚合器旨在用作子聚合器,以便可以按桶聚合最匹配的文档. top_hits聚合器可以有效地用于通过桶聚合 ...

  10. 重置zend studio 默认设置的方法[转]

    这个方法类似于手机的“恢复出厂设置”的功能,就是将所有的使用记录全部清除,用于解决zend studio使用过程中遇到的各种莫名其妙的问题,可以说是zend studio各种问题的终极解决方法~能够解 ...