今天看Scott Meyers大师的stl的用法,看到了我前段时间犯的一个错误,发现我写的代码和他提到错误代码几乎一模一样,有关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.对于节点式容器
std::list<struct> mList;
...
std::list<struct>::iterator iter = mList.begin();
for ( ; iter != mList.end(); )
{
    if (...)
    {
        //因为节点式只会导致当前节点迭代器失效,所以删除节点的同时对迭代器进行后移的操作,因为其他元素不会失效
        mList.erase(iter++);
    }
    else
    {
        ++iter;
    }
}

2.对于顺序式容器
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. c++之STL容器删除元素

    1.删除容器中特定值的元素 如果是容器vector,string,,deque,使用erase-remove 例如:erase-remove 注:因为container没有remove,contain ...

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

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

  3. STL进阶--删除元素

    删除元素 从vector或deque删除元素 vector<int> vec = {1, 4, 1, 1, 1, 12, 18, 16}; // 删除所有的1 for (vector< ...

  4. Java中ArrayList循环遍历并删除元素的陷阱

    ava中的ArrayList循环遍历并且删除元素时经常不小心掉坑里,昨天又碰到了,感觉有必要单独写篇文章记一下. 先写个测试代码: import java.util.ArrayList; public ...

  5. 顺序容器删除元素 vector list deque

    #include <iostream>#include <list>#include <algorithm>#include <string> usin ...

  6. 删除STL容器中的元素

    有关stl容器删除元素的问题,错误的代码如下: std::vector<struct> mFriendList; ... std::vector<struct>::iterat ...

  7. STL容器 erase的使用陷井

    http://www.cppblog.com/beautykingdom/archive/2008/07/09/55760.aspx?opt=admin 在STL(标准模板库)中经常会碰到要删除容器中 ...

  8. 【转】c++中Vector等STL容器的自定义排序

    如果要自己定义STL容器的元素类最好满足STL容器对元素的要求    必须要求:     1.Copy构造函数     2.赋值=操作符     3.能够销毁对象的析构函数    另外:     1. ...

  9. STL容器迭代过程中删除元素技巧(转)

    1.连续内存序列容器(vector,string,deque) 序列容器的erase方法返回值是指向紧接在被删除元素之后的元素的有效迭代器,可以根据这个返回值来安全删除元素. vector<in ...

随机推荐

  1. WinDbg 命令三部曲:(三)WinDbg SOSEX 扩展命令手册

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 系列博文 <WinDbg 命令三部曲:(一)WinDbg 命令手册> <WinDb ...

  2. 作业七:团队项目——Alpha版本冲刺阶段-02

    昨天进展:框架设计以及菜单设计. 今天安排:完善界面设计以及象棋图片的绘制. 小组一共三人,陈芝航因家里有事,与我们进行了QQ视屏会议.

  3. [C++] socket - 1 [简单TCP通信C\S代码]

    服务端: #include<iostream> #include<winsock2.h> #include<stdio.h> #pragma comment(lib ...

  4. 仿IOS 开关按钮

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. SQL order by的用法

    首先,order by是用来写在where之后,给多个字段来排序的一个DQL查询语句. 其次,order by写法: 1.  select 字段列表/* from 表名 where 条件 order ...

  6. Java CAS 和ABA问题

    独占锁:是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁:每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功 ...

  7. atitit. 统计功能框架的最佳实践(1)---- on hibernate criteria

    atitit. 统计功能框架的最佳实践(1)---- on hibernate criteria 1. 关键字 1 2. 统计功能框架普通有有些条件选项...一个日期选项..一个日期类型(日,周,月份 ...

  8. Leetcode 66 Plus One STL

    题意让大数加1 我的做法是先让个位+1,再倒置digits,然后进位,最后倒置digits,得到答案. class Solution { public: vector<int> plusO ...

  9. PHP之負載均衡下的session共用

    最近忙於開發台灣運動彩券第四版的程式,所以已經很久沒有上來寫東西了,今天隨便寫點東西和大家分享. 首先說一下負載均衡,相信大家都知道負載均衡可以很好地解決網站大流量的問題,負載均衡就是把用戶的請求分發 ...

  10. 一致性hash和solr千万级数据分布式搜索引擎中的应用

    互联网创业中大部分人都是草根创业,这个时候没有强劲的服务器,也没有钱去买很昂贵的海量数据库.在这样严峻的条件下,一批又一批的创业者从创业中 获得成功,这个和当前的开源技术.海量数据架构有着必不可分的关 ...