zoukankan      html  css  js  c++  java
  • C++迭代器失效问题(insert、erase)

    什么是迭代器

      迭代器提供了一种方法,使它能够按照顺序访问某个容器所含的各个元素,但无需暴露该容器的内部结构,换句话说迭代器就是指针的简单包装,通过一个模板类封装的对象

    迭代器的失效问题

    一、迭代器在vector、deque等内存连续的容器删除中失效


      对于序列式容器,比如vector,删除当前的iterator会使后面所有元素的iterator都失效。这是因为顺序容器内存是连续分配(分配一个数组作为内存),删除一个元素导致后面所有的元素会向前移动一个位置。(删除了一个元素,该元素后面的所有元素都要挪位置,所以,iter++,已经指向的是未知内存)。


    二、迭代器在mapsetmutilset等关联类的容器中删除不失效

      在关联类容器(mapsetmutilset)删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。

    三、迭代器在内存连续的容器中插入元素,插入位置之前的迭代器有效,之后的迭代器失效;内存非连续得容器插入迭代器不失效

      insert插入没有返回值,因此insert不能在循环中 连续的 进行插入操作(插入位置之后的迭代器失效,无法遍历)

      

      

    注意: 正常使用erase删除迭代器是有返回值的,返回的是下一个有效的迭代器,

    #include<iostream>
    #include<thread>
    #include<string>
    #include<vector>
    #include<list>
    #include<mutex>
    #include<future>
    using namespace std;
    
    int main()
    {
        std::vector<int>v{ 0, 1, 2, 3 };
    
        for (auto i = v.begin(); i != v.end(); i++)
        {
            //cout << *i << endl;
            i=v.erase(i);//迭代器i被删除之后是一个无效的迭代器(nullptr指针),因此不能对i进行任何操作;
            //erase()返回值指向下一个迭代器
            cout << *i << endl;  
        }
        system("pause");
        return 0;
    }

    vector::const_iterator 和 const vector::iterator的区别

      前者不能修改容器中的元素,如:*newiter=11 属于错误,可以修改迭代器自身,如:newiter++正确;后者可以修改指向容器的元素,如:*newiter=11正确,迭代器本身不能被修改,如:newiter++错误;

     




  • 相关阅读:
    听豆瓣架构变迁分享会总结
    业界对生成图片缩略图的做法归纳
    58和百姓网的技术学习
    减少存储过程封装业务逻辑-web开发与传统软件开发的思维模式不同
    网站速度问题排查与定位经验
    调度思想-现实中的事物与技术里面其实存在类似道理
    关于图片或者文件在数据库的存储方式归纳
    mysql单表体积和一个库设计多少张表为妥
    php的变量引用与销毁机制
    选择技术方案权衡时,考虑对其可控性很重要
  • 原文地址:https://www.cnblogs.com/-citywall123/p/13494607.html
Copyright © 2011-2022 走看看