• c++ 标准库迭代器失效


    0 容器

    标准STL序列容器:vector、string、deque和list。
    标准STL关联容器:set、multiset、map和multimap。
    非标准序列容器slist和rope。slist是一个单向链表,rope本质上是一个重型字符串
    非标准关联容器hash_set、hash_multiset、hash_map和hash_multimap。
    几种标准非STL容器,包括数组、bitset、valarray、stack、queue和priority_queue
     

    1 vector

    当push_back一个元素后,end()操作返回的迭代器肯定失效。 

    原因:因为vector的实现是数组,而且即将要插入的位置可能是end(),当扩容的时候,全部失效。

    当push_back一个元素后,capacity()的返回值发生变化,也就是说扩容了。那么之前所有的迭代器都是失效。

    原因:vector的迭代器实现上就是个指针,而扩容以后原来的元素被拷贝到新的地方,以前的地方内存归还给alloc类了

    当erase(),pop_back(),以后,end()迭代器失效,erase删除元素开始后面的元素的迭代器全部失效。

    原因:因为删除以后,元素不在有效,因此不应该再使用

    2 deque

    在deque容器首部或者尾部插入元素会使得任何迭代器失效。(可能)但是,指向元素的指针或是引用,是不会失效的。

    原因:deque的迭代器实现上不是指针,而是一个单独的类,因此begin(),和end()返回的是一个类,是值语意的。同时,头尾插入元素的时候,迭代器类会自动更新内部的某个字段。而当对迭代器解应用的时候,是直接返回这个字段的。因此迭代器end()返回的还是会失效。但是,指向元素的指针或是引用,是不会失效的。

    因为deque中的元素是几个大小相等的内存块,而push_back的时候扩容可能引起的是内部的那个小数组移动,而不会引起存储元素的数组内元素的移动。

    在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。其他元素的指针或是引用仍然有效

    原因:仍然在于,迭代器是一个单独的类,解引用返回的是内部的指针,因此删除的时候迭代器类的指针自动更新,但是被删除元素的迭代器已经传出,不能自动更新了。所以失效。

    在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效

    原因:当在中间插入元素的时候,根据插入位置在整个多个数组中的位置关系,将整个数组前移或是后移一个位置。因此之前的迭代器全部失效。

    3 List/set/map

    删除时,指向该删除节点的迭代器失效

    4 stack/queue

    这俩货没有迭代器。

  • 相关阅读:
    前端跨域整理
    URL HTML 统一资源定位器(Uniform Resource Locators)
    css属性选择器*=,|=,^=,$=,*=的区别
    JavaScript运算符 ~,~~,|,&,&&
    js获取url参数值的几种方式
    vue 常用插件集合(最全)
    Echarts曲线设置多条X轴和Y轴
    vue中引入.svg图标,使用iconfont图标库(SvgIcon组件使用)
    采用集成的Windows验证和使用Sql Server身份验证进行数据库的登录
    VS如何设置类或函数前不显示引用的数量
  • 原文地址:https://www.cnblogs.com/perfy576/p/8576347.html
Copyright © 2020-2023  润新知