遍历QMap引发异常处理
来源:互联网 发布:软件体系结构是什么 编辑:程序博客网 时间:2024/05/21 19:22
- 引言
- 常规错误遍历QMap方法
- 改进后遍历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 的用法
0 0
- 遍历QMap引发异常处理
- QMapIterator遍历QMap
- QMap遍历删除方法
- python 引发异常 raise()及异常处理
- QMap
- QMap
- QMap
- Qt容器(QMap/QHash etc)遍历
- Qt QMap与std map的遍历
- QMap和std::map的遍历
- 引发异常
- python OS-目录遍历-异常处理
- Python异常处理——try...except、主动引发异常(raise)、断言(assert)
- 引发类型为“System.OutOfMemoryException”的异常。 遍历DataGridView 获取行错误
- SqlDataReader引发的异常
- InvokeHelper调用引发异常
- Dialog显示引发异常
- taskscheduler 引发了异常
- C++强大背后
- 云适配发布2017年HTML5开发者生态报告
- vs 调用堆栈
- 创建java类中类出现is not an enclosing class
- 系列笔记11.2、观察者模式BroadcastReceiver
- 遍历QMap引发异常处理
- itoa()函数实现
- 树形结构的数据库表Schema设计
- 属性的几种初始化方法
- Samba实现共享
- CString/string 区别及其转化
- 【swift3实战】2048 教程(终)
- [二分图最大匹配] number 数论 + 匈牙利算法
- treeView Checkbox选择事件