迭代器失效,有两个层面的意思:

  1. 无法通过迭代器++,–操作遍历整个stl容器。记作: 第一层失效。
  2. 无法通过迭代器存取迭代器所指向的内存。 记作: 第二层失效。

vector是个连续内存存储的容器,如果vector容器的中间某个元素被删除或从中间插入一个元素, 有可能导致内存空间不够用而重新分配一块大的内存。 这个动作将导致先前获取的迭代器,,第一层和第二层均失效。 造成失效的两个函数:

● insert(i, value)
在迭代器i前插入一个元素value, 返回指向value迭代器
● erase(i)
删除迭代器i位置的元素, 返回指向后一个元素的迭代器

避免失效的方法:

● i = insert(i, value)
● i = erase(i)
造成失效的原因是因为内存的重新分配, 保留下来的迭代器不再指向容器中原来的元素

下面我们来看一下执行这两个操作时内存分配的具体情况:

1. erase操作

//erase操作
#include<vector>
#include<iostream>
using namespace std;
int main(){vector<int>q{1,2,3,4,5,6,7,8,9,10};int cnt = 0;int flag = 0;for(vector<int>::iterator i = q.begin(); i != q.end(); ++i){++cnt;if(cnt > 15){cout<<"gg"<<endl;break;}if(*i == 3)              //删除第三个i = q.erase(i);cout << *i << endl;cout << &(*i) << endl;}return 0;
}

output:

  10xc7215820xc7215c40xc7216050xc7216460xc7216870xc7216c80xc7217090xc72174100xc72178

输出结果分析: 当删除第3个元素以后我们发现第四个元素是紧邻第二个元素的(刚好差一个int的内存)

也就是说vector执行erase(i)后会将迭代器i之后的元素逐个向前移动一个type单位

这也就是i及i之后所有迭代器失效的原因…

2. insert操作(内存不足时)

//insert操作
//内存不够情况
#include<vector>
#include<iostream>
using namespace std;
int main(){vector<int>q{1,2,3,4,5,6,7,8,9,10};                                 //  c++11列表初始化vector<int>::iterator j = q.begin();j++;cout<<"第二个元素:"<<*j<<endl;cout<<"第二个元素地址:"<<&(*j)<<endl;cout<<"初始vector分配的容量:"<<q.capacity()<<endl;                  //  有多少元素即分配多少内存int cnt = 0;int flag = 0;  //flag保证只插入一次for(vector<int>::iterator i = q.begin(); i != q.end(); ++i){++cnt;if(cnt > 15){cout<< "gg" <<endl;break;}if(*i == 3&&!flag){flag = 1;i = q.insert(i,22);cout<<"\n插入后第二个元素:"<<*j<<endl;cout<<"插入后第二个元素地址:"<<&(*j)<<endl;cout<<"插入元素后vector分配的容量:" <<q.capacity() <<endl;}cout << *i << endl;cout << &(*i) << endl;}return 0;
}

output:

  第二个元素:2第二个元素地址:0xe5215c初始vector分配的容量:1010xe5215820xe5215c插入后第二个元素:15007936插入后第二个元素地址:0xe5215c插入元素后vector分配的容量:20220xe5219030xe5219440xe5219850xe5219c60xe521a070xe521a480xe521a890xe521ac100xe521b0

输出结果分析: vector内存分配策略为 二倍扩容 , 每次当内存不够的情况下vector会将容量扩展为当前的两倍.

那这些新分配的会在原内存的后面吗? 根据输出结果显然不是的。

上例代码在插入元素22 后, 新的3号元素内存位置距离上一个元素不是4byte(1个int单位), 也就是说

当vector扩容时, 会在另一个内存分配一段新的内存(原内存的二倍). 并把原内存中的元素全部拷贝到新内存中…

指向二号元素的迭代器在插入操作之后指向的值由2变成了15007936,也验证了上述结论.

3. insert操作(内存充足时)

//insert操作
//内存充足情况
#include<vector>
#include<iostream>
using namespace std;
int main(){vector<int>q{1,2,3,4,5,6,7,8,9,10};                             q.push_back(11);cout<<"初始vector分配的容量:"<<q.capacity()<<endl;                  int cnt = 0;int flag = 0;  //flag保证只插入一次for(vector<int>::iterator i = q.begin(); i != q.end(); ++i){++cnt;if(cnt > 15){cout<< "gg" <<endl;break;}if(*i == 3&&!flag){flag = 1;i = q.insert(i,22);cout<<"插入元素后vector分配的容量:" <<q.capacity() <<endl;}cout << *i << endl;cout << &(*i) << endl;}return 0;
}

output:

  初始vector分配的容量:2010x1f218820x1f218c插入元素后vector分配的容量:20220x1f219030x1f219440x1f219850x1f219c60x1f21a070x1f21a480x1f21a890x1f21ac100x1f21b0110x1f21b4

输出结果分析:

很显然当内存充足的情况下, 执行insert操作只会将迭代器i及i之后的的所有元素向后移动一个type单位.所以这种情况下即使没有使用返回值也不会发生迭代器失效

STL中容器vector迭代器失效的相关问题相关推荐

  1. C++中STL和容器、迭代器、算法之间的关系

    自学习C++以来,一直对STL.容器.迭代器.算法甚是困惑. 参考一些资料,加上自己的理解,整理如下 如果说程序等于数据结构+算法,STL就是一个小程序库,之所以说小,是因为容器模板中常用的函数有限, ...

  2. C++ STL : 模拟实现STL中的vector类

    文章目录 vector vector的介绍 vector的优缺点 实现时需要注意的细节问题 1. Capacity增长问题 2. memset等函数来带的按字节拷贝问题 3. 深浅拷贝问题 4. 迭代 ...

  3. STL之容器Vector内存管理

    大家都知道,STL中的vector容器的数据安排(线性空间或者叫块内存)及操作方式(支持随机访问),与array(数组)非常相似,唯一的差别在于前者为动态空间,随着元素的增加,内部机制会自动扩大空间而 ...

  4. 【C++】STL中 list 反向迭代器的模拟实现

    在上篇文章实现了 list 后,我们实现了其对应的迭代器,但是对于 list,还有一个反向迭代器我们呢没有实现,但是反向迭代器不仅仅可以在 list 中使用,在 vector 中我们进行适配,同样也可 ...

  5. STL库容器vector at函数

    STL库容器vector at函数 v.at(n)返回v指定位置n的元素.at函数比[]运算符更加安全, 因为它不会让你去访问到越界的元素,一旦越界将会在运行时中止程序并抛出一个异常std::out_ ...

  6. C++vector迭代器失效的问题

    转载:http://blog.csdn.net/olanmomo/article/details/38420907 转载:http://blog.csdn.net/stpeace/article/de ...

  7. STL的erase()陷阱-迭代器失效总结

    下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...

  8. STL源码剖析---迭代器失效小结

    迭代器(iterator)是一个可以对其执行类似指针的操作(如:解除引用(operator*())和递增(operator++()))的对象,我们可以将它理解成为一个指针.但它又不是我们所谓普通的指针 ...

  9. C++STL中的vector

    vector 容器 vector是C++标准模版库(STL,Standard Template Library)中的部分内容.之所以认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单的说: ...

最新文章

  1. c语言调式有错误,vsc调式c语言
  2. Java并发编程—线程间协作方式wait()、notify()、notifyAll()和Condition
  3. 为什么说Prometheus是足以取代Zabbix的监控神器?
  4. 来,看看你的单片机程序有多大!
  5. OC中的基本容器和基本数据类型
  6. 如何导出树结构清晰的代码机构目录
  7. EF ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象...
  8. while 循环java_Java做while循环
  9. HttpServletRequest小结
  10. MySQL 新增、修改、删除 字段 sql语句
  11. FCM算法的matlab程序
  12. 未安装任何音频输出设备 解决方案
  13. html js css 简明教程,HTML+CSS+JavaScript网页制作简明教程
  14. [转载]你们要的GIF动图制作全攻略!看完就会做!(实操教程)
  15. 2.郝斌C语言课程大纲
  16. MySQL学习笔记整理(上部)
  17. untun 安装docker 随手记
  18. 撷半盏时光,叙岁月无恙。
  19. scada如何用oracle数据库,怎样设计SCADA系统数据库存储功能及其应用
  20. MLAPP(翻译)—第一章

热门文章

  1. 搜索引擎---solr
  2. Scrum项目管理流程之站立会议
  3. 设置按钮为点击状态(被点击)
  4. 洛谷P3131 [USACO16JAN]Subsequences Summing to Sevens S 题解
  5. 一个不错的分享源码的网站
  6. STM32 TIM定时中断
  7. AWS助理架构师认证考试样题答案及解析
  8. 斯金纳的行为主义和华生的人格理论和多拉德和米勒的刺激反应理论和罗特的社会学习理论
  9. 手机摄像头驱动_手机终端大幅下单 摄像头厂商有喜有忧
  10. 区块链内容平台陀螺财经完成700W天使轮融资