容器是非常便捷常用的,经常用容器来存储多条数据,然后对数据进行增删查改。

有时要在遍历的同时删除一条数据,但是这样删除的时候程序会导致程序崩溃。

这个问题在GCC 中不会出现,而在VS2008,VS2010 中都有,其它更高VS版本未测试。

比如map 容器:

map<int, string> dataMap;
for (int i = ; i < ; ++i) {
dataMap.insert(dataMap.end(), make_pair(i, string("str")));
} map<int, string>::iterator iter = dataMap.begin();
while (iter != dataMap.end()) {if (iter->first == ) {
dataMap.erase(iter);
} ++iter;
}

当打印到3str后会引发一个Debug Assertion Failed!

这是因为使用erase 删除iter 后iter已经指向了一个无效的地址,这时下一轮循环的while 条件成立,这时再用iter->first 的时候程序就崩溃了。

再来看看vector

vector<int> dataVec;
for (int i = ; i < ; ++i) {
dataVec.push_back(i);
} vector<int>::iterator iter = dataVec.begin();
while (iter != dataVec.end()) {if ( == *iter) {
dataVec.erase(iter);
} ++iter;
}

同样也会崩溃。

对于其它容器list,deque,set,multiset,multimap 也同样会有这样的问题。

我想比较直接的办法就是把要删除的那个iter的下一个指针先临时保存一份,erase 后再重新赋值给iter,继续下一轮循环。

vector<int>::iterator iter = dataVec.begin();
vector<int>::iterator tempIter;
while (iter != dataVec.end()) { if ( == *iter) {
tempIter = iter + ;
dataVec.erase(iter);
iter = tempIter;
} else {
  ++iter;
  }
}

但是这样还是会崩溃,无奈只好把erase 调用放在循环外面,把检测出要删除的iter 临时记录一份,遍历结束后再删除。

vector<int>::iterator iter = dataVec.begin();
vector<int>::iterator tempIter;
while (iter != dataVec.end()) {
cout << *iter << endl;
if ( == *iter) {
tempIter = iter;
}
++iter;
}
dataVec.erase(tempIter);

这样就确保不会再出现崩溃了。

C++容器在遍历时的删除问题的更多相关文章

  1. STL容器的遍历删除

    STL容器的遍历删除 今天在对截包程序的HashTable中加入计时机制时,碰到这个问题.对hash_map中的每个项加入时间后,用查询函数遍历hash_map,以删除掉那些在表存留时间比某个阈值长的 ...

  2. 遍历并批量删除容器中元素出现ConcurrentModificationException原因及处置

    在以下四种遍历过程中,前两种会抛出ConcurrentModificationException,而后两种方法是正确的. Department类: package com.sitinspring; i ...

  3. java 集合list遍历时删除元素

    本文探讨集合在遍历时删除其中元素的一些注意事项,代码如下 import java.util.ArrayList; import java.util.Iterator; import java.util ...

  4. Java遍历时删除List、Set、Map中的元素(源码分析)

    在对List.Set.Map执行遍历删除或添加等改变集合个数的操作时,不能使用普通的while.for循环或增强for.会抛出ConcurrentModificationException异常或者没有 ...

  5. 【Java】List遍历时删除元素的正确方式

    当要删除ArrayList里面的某个元素,一不注意就容易出bug.今天就给大家说一下在ArrayList循环遍历并删除元素的问题.首先请看下面的例子: import java.util.ArrayLi ...

  6. 【原理探究】女朋友问我ArrayList遍历时删除元素的正确姿势是什么?

    简介 我们在项目开发过程中,经常会有需求需要删除ArrayList中的某个元素,而使用不正确的删除方式,就有可能抛出异常.或者在面试中,会遇到面试官询问遍历时如何正常删除元素.所以在本篇文章中,我们会 ...

  7. java list集合遍历时删除元素

    转: java list集合遍历时删除元素 大家可能都遇到过,在vector或arraylist的迭代遍历过程中同时进行修改,会抛出异常java.util.ConcurrentModification ...

  8. Kotlin入门(16)容器的遍历方式

    Kotlin号称全面兼容Java,于是乎Java的容器类仍可在Kotlin中正常使用,包括大家熟悉的队列ArrayList.映射HashMap等等.不过Kotlin作为一门全新的语言,肯定还是要有自己 ...

  9. STL容器及算法题:删除奇数的QQ号

    最近思考到这样一个题目:在STL的set和vector容器里存储了1亿个QQ号,编写函数删除奇数QQ号. 1. STL容器简介 首先了解一下 set 和 vector 以及其他类似的 STL 容器: ...

随机推荐

  1. android中跨进程通讯的4种方式

    转自:http://blog.csdn.net/lyf_007217/article/details/8542359 帖子写的很好.看来一遍,试了一遍,感觉太有意义.必须转过来! android中跨进 ...

  2. url 的httppost 和http get ,put,delect

    URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源 ,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作 .到这里 ...

  3. 深入浅出SlidingMenu

    如果想直接查看源码的话可以从我的Github上下载查看:https://github.com/zhanghuijun0/demo-for-android/tree/master/SlidingMenu ...

  4. 反片语(map)

    输入一些单词,找出所有满足如下条件的单词: 该单词不能通过字母重排,得到输入文本中的另外一个单词. 在判断是否满足条件时,不区分大小写,但输出保留输入中的大小写,按字典序进行排列(所有大写字母在小写字 ...

  5. 用 alias 给常用命令取个别名

    作为一名iOS开发者,很多时候需要用到命令行,有时候一长串的命令实在让人讨厌,特别是一些常用的命令,我们要一遍一遍不厌其烦的去敲键盘.但是老鸟一般都不会这么傻,因为有 alias,通过alias 我们 ...

  6. 移动端-弹窗demo

    <!doctype html> <html> <head> <meta charset="UTF-8"> <meta name ...

  7. uva 10304 - Optimal Binary Search Tree 区间dp

    题目链接 给n个数, 这n个数的值是从小到大的, 给出个n个数的出现次数. 然后用他们组成一个bst.访问每一个数的代价是这个点的深度*这个点访问的次数. 问你代价最小值是多少. 区间dp的时候, 如 ...

  8. JAVA的网络编程【转】

    JAVA的网络编程[转] Posted on 2009-12-03 18:04 火之光 阅读(93441) 评论(20) 编辑 收藏 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能, ...

  9. 寒冰王座(hd1248)

    寒冰王座 Problem Description 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店 ...

  10. 钱币兑换问题(hd1284)

    钱币兑换问题 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法.   Input 每行只有一个正整数N,N小于32768.   Output 对应每个输 ...