C++ 迭代器失效问题
迭代器的底层是通过指针来实现的,例如string类的迭代器是由char* 类型的指针实现的,vector类是由原生态指针T* 实现的。我们都知道,如果对指针使用不当,会造成程序的崩溃,所以对迭代器的操作,其实就是对指针的操作。所以我们使用时就要确保迭代器的安全性问题
迭代器失效我们就拿vector类来详细说明
1、操作已释放的空间造成迭代器失效
我们来看看以下代码
#include <iostream>
#include <vector>
using namespace std;void test()
{vector<int> v(5, 1);vector<int>::iterator it = v.begin();cout << *it << endl;//将有效字符个数置为10个v.resize(10);cout << *it << endl;
}int main()
{test();return 0;
}
运行结果:
我们会发现只是打印了一次,第二次什么都没打印。我们再通过调试查看v的容量的变化
有效字符个数和容量都发生了变化,我们知道当容量发生变化时会重新开辟一个更大的空间,然后将原来空间的数据拷贝到新的空间中,再释放原有空间。但是此时的迭代器还指向着原有空间,已经是野指针了,对野指针进行解引用当然是不可取的,会导致程序的崩溃和不安全。
所以说只要涉及到扩容,就会开辟新的空间,此时迭代器就会失效,下面这些函数都是会有可能涉及到扩容的;resize、reserve、insert、assign、 push_back等
如果存在迭代器的情况下,进行了以上函数的操作,我们只要对迭代器重新赋值就可以解决迭代器失效问题
#include <iostream>
#include <vector>
using namespace std;void test()
{vector<int> v(5, 1);vector<int>::iterator it = v.begin();cout << *it << endl;v.resize(10);it = v.begin();cout << *it << endl;
}int main()
{test();return 0;
}
运行结果
2、迭代器的指向发生了错位
我们知道vector中,每删除一个元素,前面的元素都会向前移动,补充空缺的位置。此时迭代器指向的元素已经发生了变化。
#include <iostream>
#include <vector>
using namespace std;void test()
{vector<int> v(5, 1);vector<int>::iterator it = v.begin();cout << *it << endl;//头删v.erase(it);cout << *it << endl;
}int main()
{test();return 0;
}
运行结果
我们可以发现程序已经崩溃了,但是我们知道,此时的迭代器指向的元素还是存在的呀,并没有空间的变化,那为什么会导致程序崩溃呢?假如我们删除了最后一个元素,此时的迭代器就指向了end这个位置,但是end这个位置是没有元素的,所以再对迭代器进行操作那么就会导致程序的崩溃,而在vs中的编译器就简单粗暴,无论是在哪里删除元素,迭代器就都会失效
但是在g++编译器中,并没有这么简单粗暴,只有在删除最后元素才会导致程序崩溃
运行结果:
如果存在迭代器的情况下,进行了以上述的操作,我们只要对迭代器重新赋值就可以解决迭代器失效问题
C++ 迭代器失效问题相关推荐
- C++知识点32——使用C++标准库(关联容器set和multiset的初始化,赋值,查找,添加,删除与迭代器失效)
关联容器map和multimap已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877和https://blog.csdn.ne ...
- C++知识点31——使用C++标准库(关联容器multimap及其初始化,赋值,查找,添加,删除与迭代器失效)
关于关联容器map已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877中介绍完了 multimap和map非常类似,容器中的元 ...
- C++知识点30——使用C++标准库(关联容器map及其初始化,赋值,查找,添加,删除与迭代器失效)
一.关联容器简介 关于顺序容器和关联容器的区别已经在博客https://blog.csdn.net/Master_Cui/article/details/107427911中提过 C++标准库中的关联 ...
- C++知识点24——使用C++标准库(顺序容器deque的初始化,赋值,访问,添加,删除,交换与迭代器失效)
deque容器是双端队列,使用前,需要添加#include <deque> deque的内存结构如下: 根据上图可知,deque和vector,string稍有不同,deque的内存是分段 ...
- C++知识点22——使用C++标准库(顺序容器list的初始化、赋值、访问、交换、添加、删除与迭代器失效)
list容器是双向链表,使用前,需要添加#include <list> 1.list的初始化 常用的构造函数如下 explicit list (const allocator_type&a ...
- C++知识点20——使用C++标准库(再谈string——string的大小、容量、交换与迭代器失效)
1.string的大小与容量 size_t size() const; bool empty() const; void resize (size_t n); void resize (size_t ...
- C++知识点18——使用C++标准库(vector的增长与迭代器失效)
描述vector容器对象大小的方法有以下几个 1.size():返回vector容器对象中实际的元素个数 2.empty():当size()返回0时,该函数返回true,否则返回false,判断容器对 ...
- STL的erase()陷阱-迭代器失效总结
下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...
- STL erase() 迭代器失效
STL中的容器按存储方式分为两类:序列容器(如:vector .deque.list):关联容器(如:set.map) 两种容器在使用erase方法来删除元素时或产生迭代器失效的问题 对于非顺序序列容 ...
- map和vector的迭代器失效问题(某公司招聘笔试试题)
当删除一个STL容器(比如map, vector)中的某个元素时, 会引起迭代器失效, 所以, 我们务必提高警惕. 某次笔试, 我遇到这样一个题目: 删除map<int, int>中val ...
最新文章
- OneinStack一键部署操作说明
- 域名怎么设置非80端口_深信服网关怎么设置端口映射
- 创建一个显示所有预定义WPF颜色的ListBox
- java无向图代码实例_Java 图示例 · JavaTutorialNetwork 中文系列教程 · 看云
- 针对连续动作的DQN
- workerman在linux上怎么运行,linux系统中workerman的安装步骤
- C语言扫雷游戏简单实现
- 1070. 结绳(25)
- FYR的完整形式是什么?
- 发生一个未处理的异常 脚本调试 错误号2912
- Webpack 中 resolve 路径解析
- csv文件的使用,csv空白行问题
- 日记 [2007年01月22日]QMAIL服务器完整安装手册-4
- 如何高效看懂别人代码
- php开发环境浏览器有哪些,ie内核浏览器有哪些
- 硬件知识储备01_一文看懂W25Qxx系列芯片(W25Q16、W25Q32、W25Q64...)
- 在linaro中安装opencv
- linux中rabbitmq服务启动失败,linux系统RabbitMQ启动错误记录
- 2017电子设计大赛-光电科技协会板球控制系统
- Python numpy函数:reshape()
热门文章
- python字典如何删除数据库,如何从python字典中删除?
- mysql 数据库复制软件_mysql 快速复制数据库
- linux扩容后显示管理,linux之lvm管理及扩容
- 玩转 SpringBoot 2 快速整合 | Thymeleaf 篇
- html音频自动播放隐藏控制器,HTML5 音频回放/播放控制器
- python 多列对齐_python – 如何连接两个数据帧并在这样的特定列上对齐?
- ASP.NET Core学习——7
- 666_update
- 洛谷P2181 对角线(组合数)
- 整合Flask中的目录结构