• 【经验】STL的list vector在iterator迭代器的循环中 使用erase 造成的BUG


    #include <iostream>
    #include <list>
    #include <vector>
    using namespace std;
    typedef unsigned char  BYTE;
    typedef unsigned int   UINT32;
    typedef unsigned short UINT16;
    
    struct Datastruct{
        BYTE   type;
        UINT16 length;
        UINT32 value;
        void show(){
            //cout<<" type  ="<<type;
            //C++就是这样烦人 打印出的是字符[char] 非数值 //要想以数值的形式打印 需要进行强制类型转换
            //cout.setf(ios::hex,ios::basefield);//设置十六进制显示数值
            //cout.setf(ios::showbase|ios::uppercase);//设置0x头和大写
            cout<<" type  ="<<(int)type;
            //printf(" type  =",type);//还是C语言方便
            cout<<" length="<<length;
            cout<<" value ="<<value<<endl;
        }
    };
    list<Datastruct> datalist;
    void data_init(){
        Datastruct data;
        data.type=1;
        data.length=7;
        data.value=1;
        datalist.clear();
        for(int i=0;i<4;i++){
            data.value+=i;//1 2 4 7
            datalist.push_back(data);
        }
    }
    void data_show(){
        for(list<Datastruct>::iterator datait=datalist.begin();datait!=datalist.end();datait++){
            datait->show();
        }
    }
    int main(int argc,char **argv)
    {
        //初始化 list
        data_init();
        
        data_show();
        //删除 value是偶数的 BUG:删除不完全  因为erase,只循环了2次
        for(list<Datastruct>::iterator datait=datalist.begin();datait!=datalist.end();datait++){
            if(datait->value%2==0){
                datait=datalist.erase(datait);
            }
        }
        cout<<"================================"<<endl;
        data_show();
        data_init();
        
        //删除 value是偶数的 BUG:删除不完全  因为erase,只循环了2次
        for(list<Datastruct>::iterator datait=datalist.begin();datait!=datalist.end();datait++){
            if(datait->value%2==0){
                datait=datalist.erase(datait);
                datait--;
            }
        }
        cout<<"================================"<<endl;
        data_show();
        
        return 0;
    }
    /*********
     type  =1 length=7 value =1
     type  =1 length=7 value =2
     type  =1 length=7 value =4
     type  =1 length=7 value =7
    ================================
     type  =1 length=7 value =1
     type  =1 length=7 value =4
     type  =1 length=7 value =7
    ================================
     type  =1 length=7 value =1
     type  =1 length=7 value =7
     
    ***********/

    最关键的代码:

     datait=datalist.erase(datait);

    其实,后面跟一个 it -- ; 指向前一个 ,再配合 for循环里面的 it++ ,才能保证正确性!

    由于不清楚 STL的源码中到底怎么处理 迭代器的.所以 造成 使用不当。 在www.cplusplus.com 中的erase例子 不够好,配合源码 以及经常更新的例子 才能让我们更加理解其工作原理。

  • 相关阅读:
    LINUX重启MYSQL的命令
    如何在linux下实现mysql数据库每天自动备份
    mysql 2013错误解决
    mysql按年度、季度、月度、周、日统计查询的sql语句
    MySQL 时间戳(Timestamp)函数
    jQuery 选择器大全总结
    使用Git的Push出现rejected
    js实现分页的几个源码,看完基本就懂了
    Get,Post请求中文乱码问题有效解决方法
    web应用中文乱码问题的原因分析
  • 原文地址:https://www.cnblogs.com/ayanmw/p/3678504.html
Copyright © 2020-2023  润新知