【C++】vector,list迭代器失效

news2024/9/21 2:40:34

1.vector迭代器失效

vector容器的物理基础是线性表,底层是指针变量实现的。

在这里导致vector迭代器失效的原因会有两种-----插入失效,删除失效

1.2插入数值导致迭代器失效

1.21扩容导致迭代器失效

我们在一块vector空间插入pos(20)

 但是这个空间只能存放五个数,要想插入数据,就要重新扩容2倍(一般扩容时,二倍是比较合理的)。

 当释放小空间时,pos迭代器仍然指向他,所以释放后,pos就是野指针了,所以造成pos迭代器失效。

举个例子:我们在所有的偶数前面插入这个偶数的2 倍,由于我们写的迭代器可能存在误差,我们直接调用std库里的迭代器进行测试。

int main()
{
	std::vector<int> v;  //调用std中的vector
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			v.insert(it, *it * 2);
		}
		++it;
	}
	for (auto e : v)
	{
		cout << e << endl;
	}
	return 0;
}

1.22pos指向位置改变导致迭代器失效 

对于上面的代码我们直接给他扩容让他空间足够。

int main()
{
	std::vector<int> v;  //调用std中的vector
	v.reserve(10);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			v.insert(it, *it * 2);
		}
		++it;
	}
	for (auto e : v)
	{
		cout << e << endl;
	}
	return 0;
}

 编译直接报错,为啥空间足够,迭代器也会失效呢?

按我们所想的代码,打印的是1,4,2,3,8,4,5。。。但是这全部是2,而且还是在同一个地方,不是在偶数前面插入的4。

这个原因是啥?

我们加入数据2的下标是[1]当我们插入4后,我们想让下标进行移动到数据3处,但是这个下标现在在数据4的下标[1]处,然后下标++,到数据2的下标[2]处,诶我们发现,这个下标转转回回又到了数据2处,然后又在他前面插入。所以会一直插入4在2前面

所以我们可以用一个指针去接收插入后的迭代器。

int main()
{
	std::vector<int> v;  //调用std中的vector
	v.reserve(10);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			it=v.insert(it, *it * 2);
			it += 2;
		}
		else {
			++it;
		}
		
	}
	for (auto e : v)
	{
		cout << e << endl;
	}
	return 0;
}

如果按照第一种情况,扩容使迭代器失效,那我们不扩容看看加一个指针接收还会不会失效。

如果我们不用指针接收,单纯让it每次+2行吗?

不扩容的情况不行: 

 而扩用的可以,但是用指针接收也不费事,别用这两种代码。

1. 3删除erase导致迭代器失效

接下来我们删除vector中的偶数,看看能不能正常运行。

int main()
{
	std::vector<int> v;  //调用std中的vector
	v.reserve(10);
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			v.erase(it);
		}
			++it;
	}
	for (auto e : v)
	{
		cout << e << endl;
	}
	return 0;
}

迭代器又一次失效了。

这个是因为当我们删除2后,pos指针的位置还在原来的位置,但是3却往前挪了,而pos指向3时编译器认为指针不在指向原来的数据发生改变,所以迭代器就会失效。 

 这个解决方法也是指针接收。

 这里的it不用加两回了,因为删除本身就是一个加号。

2.list迭代器失效 

相对于底层是顺序表的vector来说,list的底层是链表,这就使他在插入时不需要大量挪动数据。也就是说list在进行插入插入操作时不会迭代器失灵。 

vector在插入时出现了野指针问题,但是在list中,插入时会创造一个新节点,指针仍旧指向原来那个结点,不会出现野指针。但是删除操作就会导致迭代器失效了。因为结点删除了但是指针还在,指针就是野指针了。 

2.1删除导致迭代器失效: 

但是list容器在删除是也会导致迭代器失效问题,情况如下:

int main()
{
	std::list<int> lt;  
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(4);
	lt.push_back(5);
	lt.push_back(8);
	lt.push_back(10);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	auto pos = find(lt.begin(), lt.end(), 5); //在list范围找5
	if (pos != lt.end())
		{
			lt.erase(pos);
			pos++;
		}
	

	for (auto e : lt)
	{
		cout << e << " ";
	}
	return 0;
	
}

 就比如我们要删除5,那么这个结点被删除之后而pos指针就变成野指针了。

也就是删除操作时会使迭代器失效。

这里把pos++代码去掉,就可以正常运行了。

总结:迭代器之所以失效最大的原因是成为野指针了。

 总是感觉这篇博客有一点水,但是真没内容写了,就这吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三章 单向链表的讲解与实现

初阶数据结构 第一章 时间复杂度和空间复杂度 第二章 动态顺序表的实现 第三章 单向链表的讲解与实现 文章目录初阶数据结构前言一、什么是链表&#xff1f;二、节点的定义&#xff1a;三、单向链表接口函数1、打印&#xff1a;2、尾插&#xff1a;3、头插&#xff1a;4、尾删…

改进YOLOv7系列: 最新结合用于小目标的新CNN卷积构建块

&#x1f4a1;统一使用 YOLOv7 代码框架&#xff0c;结合不同模块来构建不同的YOLO目标检测模型。&#x1f31f;本项目包含大量的改进方式,降低改进难度,改进点包含【Backbone特征主干】、【Neck特征融合】、【Head检测头】、【注意力机制】、【IoU损失函数】、【NMS】、【Loss…

Linux-进程控制

进程控制进程创建fork函数写时拷贝fork常规用法fork调用失败的原因进程终止进程等待进程程序替换程序替换的原理如何程序替换进程创建 fork函数 fork之前父进程独立运行&#xff0c;fork之后&#xff0c;父子两个执行流分别执行。 进程具有独立性&#xff0c;代码和数据必须独立…

机器学习HMM模型

目录1 马尔科夫链1.1 简介1.2 经典举例1.3 小结2 HMM简介2.1 简单案例2.2 案例进阶2.2.1 问题阐述2.2.2 问题解决3 HMM模型基础3.1 什么样的问题需要HMM模型3.2 HMM模型的定义3.3 一个HMM模型实例3.4 HMM观测序列的生成3.5 HMM模型的三个基本问题4 前向后向算法评估观察序列概率…

计算机毕业设计-SSM高校社团招新系统-JavaWeb大学生社团管理系统-源码+文档+讲解

注意&#xff1a;该项目只展示部分功能&#xff0c;如需了解&#xff0c;评论区咨询即可。 本文目录1.开发环境2.系统的设计背景3 前后台功能设计3.1 前台功能3.2 后台功能4 系统页面展示4.1 学生功能模块展示4.2 干部功能模块展示4.3 管理员功能模块展示5 更多推荐6 部分功能代…

如何用IDEA提高你的开发效率

前言 ​ 作为一名java开发工程师&#xff0c;IDEA无疑是我日常接触最多的工具。因此&#xff0c;能否高效使用IDEA软件&#xff0c;一定程度上决定了我们的开发效率。本文将主要介绍IDEA中的四个便于提高开发效率的功能&#xff0c;常用快捷键、实时模版、后缀补全、文件和代码…

《本地计算机DNS缓存文件》

C:\Windows\System32\drivers\etc 36.152.44.95 www.baidu.com 正常访问www.baidu.com可以DNS抓包&#xff0c;将百度的IP及域名加入文件位置的hosts文件中即该IP和域名将不再请求网络上的DNS服务器&#xff0c;即加快域名解析&#xff1b; 具体作用&#xff1a; 1.加快域名解…

什么是RPC框架?

什么是RPC&#xff1f; In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it wer…

创新能力 | 产品经理实践中常犯的七大错误

做产品是一个既感性又理性的过程&#xff0c;纵然有很多前辈同行的经验传承和技巧指导&#xff0c;但在落到实处是时&#xff0c;总难免犯一些错误。有些是经验不足导致&#xff0c;有些则是产品经理对于人性的浅见寡闻。本文作为产品经理实践指南专题的中级篇&#xff0c;阐述…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (2)-走马灯

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…

全球名校AI课程库(35)| 辛辛那提大学 · 微积分Ⅱ课程『MATH101 Calculus II』

&#x1f3c6; 课程学习中心 | &#x1f6a7; CS数学基础课程合辑 | &#x1f30d; 课程主页 | &#x1f4fa; 中英字幕视频 | &#x1f680; 项目代码解析 课程介绍 Trefor Bazett 教授在 Cincinnati 大学任教时&#xff0c;制作了两套完整的的数学课程&#xff08;微积分、离…

Eclipse创建Servlet项目-7

目录 1、创建动态 Web 项目 2、使用 Eclipse 创建 Servlet 3、配置 web.xml 4、部署项目并启动服务器 通过前面的学习&#xff0c;我们了解了如何在 Tomcat 目录下手动部署 Servlet&#xff0c;这种方式不但效率低下&#xff0c;而且容易出错。因此&#xff0c;在实际开发中…

变量常量,基本数据类型及数据类型转换

⭐️ 变量常量与基本数据类型及数据类型转换 &#x1f4cd; 来自&#xff1a;中南林业科技大学软件协会学术部&#xff1a;谢添 ⏲ 时间&#xff1a;2022 - 10 - 29 至 2022 - 10 - 30 &#x1f3e0; 官网&#xff1a;https://www.csuftsap.cn/ ✏️ 本章所有提供代码均已测…

四旋翼无人机学习第4节--STM32、MPU9250等器件的绘制

0 前言 当画stm32、mpu9250这种多引脚的芯片&#xff0c;就需要参考芯片手册啦。 这里给大家推荐一个芯片手册查询网站。 半导小芯-芯片查询工具 进入网站&#xff0c;输入芯片的具体名称&#xff0c;点击查询即可。 最后点击下载即可。 1 stm32芯片手册引脚查询 选择引脚…

学习在Git项目中使用子模块(图文教程)

一般认为 父项目 是当前正在做的主要工作&#xff0c;但需要依赖 子模块 中提供的算法或者工具。父项目 与 子模块 不是同一批人维护的&#xff0c;或者是需要分开维护的。 此情此景&#xff0c;需要学习该教程了&#xff01;&#xff01;&#xff01; 文章目录1 如何在父项目…

基于Java的一个可自由拖拽的BI可视化系统(附源码)

介绍 这是一个可自由拖拽的BI可视化系统支持主流的关系数据&#xff1a;MySQL&#xff0c;Oracle&#xff0c;PostgreSQL等同时支持Apache Doris&#xff0c;这个一开始初衷就是为了 Doris 数据可视化分析做的后端框架使用了若依 功能 按项目管理数据看板看板具备分享功能可以…

每天五分钟机器学习:超平面分离定理和凸优化

凸集和凸函数 在点集拓扑学与欧几里得空间中,凸集是一个点集,其中每两点之间的直线上的点都落在该点集中。如下所示: 函数任意两点(x,f(x))和(y,f(y))连线上的值大于(x,y)区间内任意一点m的值f(m),那么这个函数就是一个凸函数: 超平面分离定理 空间中存在两类样本,…

【CV】第 3 章:使用 OpenCV 和 CNN 进行面部检测

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

JavaScript语法知识笔记(一)——书写方式,输入出语句,变量,字面量,标识符,数据类型。

01.JS的三种书写方式 <!-- 2.内嵌式的js --><script>// alert(sajmo);</script><!-- 3.外部js script 双标签 --><script src"script.js"></script> <!-- JS代码需要写到script标签中 --><script type"text/jav…

软考高级-系统架构师-案例分析-架构设计真题考点汇总

2010年-2021年(不包括2019年和2020年)涉及到架构设计考点的有: 2010年题1,4; 2011年题1,4; 2012年题1; 2013年题1,4; 2014年题1,4; 2015年题1; 2016年题1; 2017年-题1; 2018年题1,5; 2021年题1 1.软件架构风格 软件架构风格是描述特定软件系统组织方式和惯用模式。组织方式描述…