zoukankan      html  css  js  c++  java
  • 遍历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操作的失败并引起进程的异常。

    总结

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

    参考

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

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

    注意:

    iterator QMap::end ()

    返回一个stl风格迭代器指向map最后一个项目之后的虚构项目。
  • 相关阅读:
    如何理解redo和undo的作用
    自建NAS如何使用大于2TB的硬盘(从分区开始)
    Oracle 了解 DDL 操作与 REDO 的关系
    oracle 控制文件的重建
    Oracle 表空间的日常维护与管理
    解决debian 9 重启nameserver失效问题
    Vmware复制完好的linux目录后网卡操作
    RHEL6.X设置163yum源
    【转载】Eclipse快捷键大全
    【转】Java:String、StringBuffer和StringBuilder的区别
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/8670844.html
Copyright © 2011-2022 走看看