引言

用常规方法遍历QMap,删除满足条件元素时出现“读取位置0xXXX时发生访问冲突”。查看“调用堆栈”指向QMap<int,int>::iterator::operator++()QMapNode<int,int>::nextNode()

定位为删除iterator中元素引起iterator的遍历异常,特记录如下:

常规错误遍历QMap方法

QMap<int,int>::iterator iter; //遍历map
for (iter = TimerMap_T1_I->begin(); iter != TimerMap_T1_I->end(); iter++)
{
if (tempNR>=iter.key())//如果键值对中发送序号小于或等于该tempNR对应的T1计时器复位,并移出键值对
{
killTimer(iter.value());
TimerMap_T1_I->erase(iter);
}
}

错误在于: iter指针在元素被删除后失效了,回到for语句中与 TimerMap_T1_I->end()进行比较时发生错误

改进后遍历QMap方法

QMap<int,int>::iterator iter; //遍历map
for (iter = TimerMap_T1_I->begin(); iter != TimerMap_T1_I->end(); )
{
if (tempNR>=iter.key())//如果键值对中发送序号小于或等于该tempNR对应的T1计时器复位,并移出键值对
{
killTimer(iter.value());
TimerMap_T1_I->erase(iter++); //满足删除条件,删除当前结点,并指向下面一个结点
}
else
{
iter++;//条件不满足,指向下面一个结点
}
}

TimerMap_T1_I->erase(iter++) 中map中在删除iter的时候,先将iter做缓存为iter1,然后执行iter++使之指向下一个结点,再进入erase函数体中执行删除操作,删除时使用的iter其实是缓存下来的iter1(也就是当前iter(做了加操作之后的iter)所指向结点的上一个结点)。 
这和TimerMap_T1_I->erase(iter); iter++;这种执行序列是不相同的。前者在erase执行前进行了加操作,在iter被删除(失效)前进行了加操作,是安全的;后者是在erase执行后才进行加操作,而此时iter已经被删除(当前的迭代器已经失效了),对一个已经失效的迭代器进行加操作,行为是不可预期的,这种写法势必会导致 map操作的失败并引起进程的异常。

总结

  1. QMap在进行 erase 之后,当前迭代器会失效
  2. ++操作符前置和后置的特性

参考

stl map高效遍历删除的方法 
在遍历中使用 iterator/reverse_iterator 进行 Erase 的用法

转自:https://blog.csdn.net/lm409/article/details/69257827

注意:

iterator QMap::end ()

返回一个stl风格迭代器指向map最后一个项目之后的虚构项目。

遍历QMap引发异常处理的更多相关文章

  1. HTML5本地存储localStorage、sessionStorage基本用法、遍历操作、异常处理等

    HTML5 的本地存储 API 中的 localStorage 与 sessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localSt ...

  2. C#基础知识 简单说明泛型的优点

    有关泛型的优缺点在网上有很多篇文章,也足以说明问题,我就不去复制粘贴了(而且内容有些多),由于记性不太好,所以自己做个简单明了的总结. 泛型的优点主要有两个: "性能" " ...

  3. JDK源码分析(1)ArrayList

    JDK版本 ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomA ...

  4. Java - 35 Java 实例

    Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...

  5. Python os.md

    os 便携式访问操作系统的特定功能.os模块提供了对特定平台模块(如posix, nt, mac)的封装, 函数提供的api在很多平台上都可以相同使用, 所以使用os模块会变得很方便. 但不是所有函数 ...

  6. wk_06.md

    IO与文件操作 文件内建函数open 内建函数open提供了初始化输入/输出(I/O)操作的通用接口.open()内建函数成功打开文件后会返回一个文件对象.open函数的语法如下: open(file ...

  7. js的同步异步

    由于js没有多线程,所以处理多任务的时候,可以用异步回调来解决.js中setTimeout.setInterval.ajax(jq中可以选择同步或异步)均会开启异步.遇到异步模块,会将其推入值任务队列 ...

  8. Java-Runoob-高级教程:Java 实例

    ylbtech-Java-Runoob-高级教程:Java 实例 1.返回顶部 1. Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. ...

  9. Java 实例

    Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...

随机推荐

  1. 菜鸟学SSH(五)——Struts2上传文件

    上传文件在一个系统当中是一个很常用的功能,也是一个比较重要的功能.今天我们就一起来学习一下Struts2如何上传文件. 今天讲的上传文件的方式有三种: 1,以字节为单位传输文件: 2,Struts2封 ...

  2. C语言发展历程及其保留字(关键字)——附:C语言标准文档

    引言         抽时间对C语言发展历程和C语言的标准库文件及其保留字/关键字做了个梳理,后面附C语言各版本国际标准. C语言发展历程及其标准库 C语言关键字/保留字 C语言国际标准       ...

  3. Spring Boot中扩展XML请求和响应的支持

    在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...

  4. VLAN,GRE,VXLAN

    https://www.cnblogs.com/charles1ee/p/6629009.html VLAN介绍 局域网LAN(多个机器连接一个Hub或者Switch),是一个广播域 VLAN:一台S ...

  5. 银联在线支付B2C UnionPay.NET

    新春即将来临,首先给大家拜个早年,祝攻城狮们新年快乐.万事如意.合家欢乐.团团圆圆.幸福健康.来年更能大展宏图 实现各自的梦想! 同时预祝各大科技公司大佬们事业蒸蒸日上.公司转型突破创新.冲出突围带领 ...

  6. ZooKeeper示例 分布式锁

    [转载请注明作者和原文链接,  如有谬误, 欢迎在评论中指正. ] 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程 ...

  7. sql乘法函数实现方式

    sql中有很多聚合函数,例如 COUNT.SUM.MIN 和 MAX. 但是唯独没有乘法函数,而很多朋友开发中缺需要用到这种函数,今天告诉大家一个不错的解决方案 logx+logy=logx*y 这是 ...

  8. PHP文件常用函数

    feof() 判断文件是否超出了文件末尾. <?php $files = fopen("1.txt","r+"); fread($files,filesi ...

  9. IDEA无法启动debugger,报错Address localhost:1099 is already in use

    Address localhost:1099 is already in use http://blog.csdn.net/huazhongkejidaxuezpp/article/details/4 ...

  10. adi 程序烧写

    3.2 U-Boot Console Output Here we need set up minicom to open target board serial console. sudo mini ...