使用vector需谨慎!尤其是还没有清楚vector的实现原理的时候!

头文件<vector>中对于失效的检测方式,定义是这样的:

当erase了vector中的一个元素后,不能保证原先指向有效位置的iterator仍然有效。
即:
任何insert或push操作都可能导致迭代器失效。当编写循环将元素插入到vector或deque容器中时,程序必须确保迭代器在每次循环后都得到更新。

vector::end返回的迭代器指向窗口最后一个元素的后面一个元素,这是一个理论上的元素,并不指向容器中实际的元素。
所以不能对其进行解引用操作。

我原来的想法(不正确,但也是一种考虑的角度)

首先定义了两个迭代器:
iter1
iter2
这两个迭代器同时使用时,删除vector元素会遇到的坑:

假定让iter1从头开始遍历,用iter2删除vector中的元素。为了保证不越界每次iter++之前,检查iter1是否指向end。
但是每一次都报越界的错误。为什么呢?
因为用iter2删除的时候,可能删除不止一个。删着删着,iter1指向的地址被删除了,iter1变成了野指针。你以为能够检查一个野指针是否指向有效地址,而没有考虑到检察本身就需要打开iter1,而对iter1解引用,肯定越界。

正确的解释

众所周之,当使用一个容器的insert或者erase函数通过迭代器插入或删除元素"可能"会导致迭代器失效,因此,很多建议都是:让我们获取insert或者erase返回的迭代器,以便用重新获取新的有效的迭代器进行正确的操作。

迭代器失效的原因如下:

当我们插入一个元素时它的预分配空间不够时,它会重新申请一段新空间,将原空间上的元素 复制到新的空间上去,然后再把新加入的元素放到新空间的尾部,以满足vector元素要求连续存储的目的。而后原空间会被系统撤销或征做他用,于是指向原 空间的迭代器就成了类似于“悬垂指针”一样的东西,指向了一片非法区域。(对这种整体空间转移的理解,类似于我的另一篇博客C语言 realloc函数 带着内存游走的函数

如果使用了这样的迭代器,会导致严重的运行时错误就变得很自然了。这也是许多书上叙述vector在insert操作后“可能导致所有迭代器实效”的原因。

别人也有过同样的问题,可以参考理解(见代码)

问题:
按理说在l_vData.end()前插入元素i后,it++,下次就又可以在l_vData.end()前插入元素了,但是如果用it++,程序运行会出错。为什么?

#include <vector>
#include <iostream>void main(int argc, char** argv)
{std::vector<int> l_vData;std::vector<int>::iterator it = l_vData.end();for(int i = 0; i < 10; i++){l_vData.insert(it, i);// it++;    // 为什么这样会运行报错it = l_vData.end();    // 这样没问题std::cout << l_vData[i] << std::endl;}system("pause");return;
}

关于vector的迭代器失效的问题相关推荐

  1. map和vector的迭代器失效问题(某公司招聘笔试试题)

    当删除一个STL容器(比如map, vector)中的某个元素时, 会引起迭代器失效, 所以, 我们务必提高警惕. 某次笔试, 我遇到这样一个题目: 删除map<int, int>中val ...

  2. C++知识点18——使用C++标准库(vector的增长与迭代器失效)

    描述vector容器对象大小的方法有以下几个 1.size():返回vector容器对象中实际的元素个数 2.empty():当size()返回0时,该函数返回true,否则返回false,判断容器对 ...

  3. STL中容器vector迭代器失效的相关问题

    迭代器失效,有两个层面的意思: 无法通过迭代器++,–操作遍历整个stl容器.记作: 第一层失效. 无法通过迭代器存取迭代器所指向的内存. 记作: 第二层失效. vector是个连续内存存储的容器,如 ...

  4. 【C++】vector的模拟实现@STL —— 迭代器失效问题

    vector的模拟实现@STL 1. (constructor) & (destructor) 2. 一系列基本接口 2.1 size & capacity 2.2 [] 2.3 it ...

  5. C++知识点30——使用C++标准库(关联容器map及其初始化,赋值,查找,添加,删除与迭代器失效)

    一.关联容器简介 关于顺序容器和关联容器的区别已经在博客https://blog.csdn.net/Master_Cui/article/details/107427911中提过 C++标准库中的关联 ...

  6. C++知识点24——使用C++标准库(顺序容器deque的初始化,赋值,访问,添加,删除,交换与迭代器失效)

    deque容器是双端队列,使用前,需要添加#include <deque> deque的内存结构如下: 根据上图可知,deque和vector,string稍有不同,deque的内存是分段 ...

  7. C++知识点22——使用C++标准库(顺序容器list的初始化、赋值、访问、交换、添加、删除与迭代器失效)

    list容器是双向链表,使用前,需要添加#include <list> 1.list的初始化 常用的构造函数如下 explicit list (const allocator_type&a ...

  8. C++知识点20——使用C++标准库(再谈string——string的大小、容量、交换与迭代器失效)

    1.string的大小与容量 size_t size() const; bool empty() const; void resize (size_t n); void resize (size_t ...

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

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

最新文章

  1. 百度股价接连暴涨的背后,看Apollo的2020
  2. hadoop学习-Netflix电影推荐系统
  3. 硅谷创业公司的成长道路
  4. C/C++中static的用法全局变量与局部变量
  5. php字符串转二进制数组中,如何将php字符串转成二进制
  6. Oracle function注释
  7. meta标签是什么,通常包含哪些内容?
  8. 苹果mac笔记本部分按键失灵,为什么要5连按⌥ option键
  9. iGrimaceV8 V8在线威锋源apt.so/tuzhurenv8手机直接下载安装教程图:
  10. python切片负数_Python切片
  11. winforms 文本框_在禁用的VB.Net WinForms文本框中自定义颜色的新方法
  12. android百度地图路线查询,Android百度地图——路线规划搜索
  13. 微信小程序云开发 操作数据库-简单数据的查询
  14. 区块链基础知识与关键技术解析
  15. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java面向新手投资者的虚拟股票交易系统h1o29
  16. Formatter(格式化)和 Converter(格式化)
  17. 掉头发了--偏方一大堆
  18. 红包封面发货平台 卡密系统 全新红包封面平台 可搭建分站 独立后台的源码
  19. WIN7+MySQL+ActivePerl+bugzilla+Apache安装配置
  20. Linux中sysstat服务,Linux系统维护常用工具sysstat

热门文章

  1. EOJ_1081_朋友圈
  2. python咖啡名称提取_(转)Python中文全攻略
  3. 26.PhantomData幽灵数据.rs
  4. twisted.internet.error.TimeoutError错误的解决方法
  5. 深入理解重要的编程模型
  6. Kafka端到端审计
  7. OS- -内存之虚拟内存
  8. Qt的Socket通信
  9. 腾讯视频P2P带宽节省率持续提升之路
  10. 【专场】揭秘端到端视频技术