• 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++错误;

     




  • 相关阅读:
    Asp.net 表单打印时的样式设置【原】
    Asp.net页面编辑时怎样获取隐藏列的值【原】
    C# Winform 捕获窗体的最小化和最大化事件、关闭按钮事件【整理】
    SQL 快速删除表数据并不生成日志的语句【搜藏】
    Asp.net 前段页面控件 filedset 对应的服务端控件【原】
    Asp.net 关于 HTTP403 – 访问错误 的原因及解决【原】
    Js对一个对象应用滤镜的几种方法【整理】
    Asp.net 查找不到动态创建的控件之解决办法【整理】
    C# windows service承載遠程對象
    自己写的一个日志记录类
  • 原文地址:https://www.cnblogs.com/-citywall123/p/13494607.html
Copyright © 2020-2023  润新知