遍历QMap引发异常处理
引言
用常规方法遍历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操作的失败并引起进程的异常。
总结
- QMap在进行 erase 之后,当前迭代器会失效
- ++操作符前置和后置的特性
参考
stl map高效遍历删除的方法
在遍历中使用 iterator/reverse_iterator 进行 Erase 的用法
转自:https://blog.csdn.net/lm409/article/details/69257827
注意:
iterator QMap::end ()
遍历QMap引发异常处理的更多相关文章
- HTML5本地存储localStorage、sessionStorage基本用法、遍历操作、异常处理等
HTML5 的本地存储 API 中的 localStorage 与 sessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localSt ...
- C#基础知识 简单说明泛型的优点
有关泛型的优缺点在网上有很多篇文章,也足以说明问题,我就不去复制粘贴了(而且内容有些多),由于记性不太好,所以自己做个简单明了的总结. 泛型的优点主要有两个: "性能" " ...
- JDK源码分析(1)ArrayList
JDK版本 ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomA ...
- Java - 35 Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...
- Python os.md
os 便携式访问操作系统的特定功能.os模块提供了对特定平台模块(如posix, nt, mac)的封装, 函数提供的api在很多平台上都可以相同使用, 所以使用os模块会变得很方便. 但不是所有函数 ...
- wk_06.md
IO与文件操作 文件内建函数open 内建函数open提供了初始化输入/输出(I/O)操作的通用接口.open()内建函数成功打开文件后会返回一个文件对象.open函数的语法如下: open(file ...
- js的同步异步
由于js没有多线程,所以处理多任务的时候,可以用异步回调来解决.js中setTimeout.setInterval.ajax(jq中可以选择同步或异步)均会开启异步.遇到异步模块,会将其推入值任务队列 ...
- Java-Runoob-高级教程:Java 实例
ylbtech-Java-Runoob-高级教程:Java 实例 1.返回顶部 1. Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. ...
- Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...
随机推荐
- [LeetCode] Meeting Rooms I & II
Meeting Rooms Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s ...
- Vivado神器之DocNav
Vivado2014安装完成以后会有2个文件出现在桌面上,具体如下图: 上一个是vivado的软件,是主要的工具,但是一定不要忽略下面一个DocNav,今天我要讲的就是这个工具,打开一个会看到这样一个 ...
- UIView的alpha、hidden和opaque属性之间的关系和区别
转自:http://blog.csdn.net/wzzvictory/article/details/10076323 作者:wangzz 原文地址:http://blog.csdn.net/wzzv ...
- (UML总结三)UML与软件project
学习完UML.我们要把它和之前的软件project结合起来.软件project是从总体的角度说了软件开发的步骤.保证了所开发软件的质量.而UML作为一种统一建模语言.是用来设计软件蓝图的可视化建模语言 ...
- 精通Docker的50个必备教程、工具、资源
Docker 已经震惊了软件开发界.它提供了一种根据 DevOps 方法打包和输送应用程序的便捷方法. 最近我们发布了 51 个必备的 Docker 工具列表①,但工具不是完全精通容器化所需的唯一东西 ...
- mysql trigger 触发器
创建触发器: CREATE [DEFINER = {user|CURRENT_USER}] TRIGGER trigger_name trigger_time trigger_event ON tbl ...
- java二维数组遍历
数组名加上length(arr.length),表示该数组的行数(Row): 指定索引加上length(arr[x].length),表示该行的元素个数,即该行的列数(Column). public ...
- 关于 android receiver
可以在代码文件中声明一个receiver,也可以在manifest中声明一个,前者中的receiver只有在该activity launch起来以后才会监听其所感兴趣的事件,而如果在androidMa ...
- Silverlight-MEF-DEMO
“托管扩展性框架(Managed Extensibility Framework,简称MEF),是微软.NET框架下为提高应用和组件复用程度而推出的,用于使组件能够最大化的重用.使用MEF能够使静态编 ...
- S3C2440时钟体系结构
任意一款单板,我们了解其时钟都是通过时钟树来的. 这里没有全部截完,只是讲解时钟来源,OSC代表晶振,这说明我们的时钟可以来至晶振OSC也可以来至外部输入EXTCLK,这是通过OM选择器来完成的. 2 ...