vector迭代器失效

news2024/9/28 5:29:04

目录

迭代器失效的场景

insert插入元素时迭代器失效

erase删除元素时迭代器失效


本期我们主要进行vector迭代器失效问题的讨论。

迭代器失效的场景

insert插入元素时迭代器失效

先看代码:

iterator insert(iterator pos, T val)
		{
			assert(pos >= _start);
			assert(pos <= _finish);
			size_t length = pos - _start;
			if (_finish == _endofstorage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}
			pos = _start + length;
			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				end--;
			}
			_finish--;
			*pos = val;
			return pos;
		}

insert插入元素时为什么会导致迭代器时效呢?其实这主要是在插入元素时,空间不够,扩容导致的。

 解析:如图,假设在pos位置插入一个元素,但是此时空间不够,所以我们进行了扩容。但是扩容之后此时的pos仍然指向了之前的位置,所以此时的pos就已经失效了(这就称作迭代器失效),所以我们得通过pos-_start的值计算出来pos位置与_start的位置,然后在扩容之后,通过差值计算出来真正的pos的位置。需要注意的是,我们此时的正确位置只是形参里pos的正确位置,但是实参是没有发生变化的,因为insert形参列表中的pos位置传的是实参pos的值,所以我们得通过返回值的方式返回扩容后正确的pos位置。

erase删除元素时迭代器失效

 我们要删除vector中的偶数元素,此时erase失效场景有三种:

第一种:

解析:思想:我们要删除所有的偶数所以先让pos指向第一个元素的位置,如果不是偶数就 + +如果pos位置的元素是偶数就删除pos 位置的元素,删除元素的思想其实就是把要删除的元素的后面的所有元素统一往前移动一个位置,这样就删除了要删除的元素。对于第一种情景,我们发现,确实是删除了所有的偶数。
注意: end表示最后一个元素的位置的下一个位置。 

第二种:

解析:跟第一种情景的思想是一样的,但是到最后会产生迭代器失效,在删除了元素之后,我们会先将指向了删除了的元素的位置的指针+ +,然后再将finish--但是这样会产生一种极端的情况,如图,就是当最后一个元素是偶数时,我们将最后一个元素删除之后,先将指向了最后一个元素的指针++,然后将finish--,这就导致了pos和 finish错位,因为循环的终止条件是pos<_finish,因为pos和 finish错位,这就导致循环不会终止,所以这种情况是有问题的。

第三种:

解析:这种情景我们称作连续偶数的情景,在这种情景下,同样是因为,我们再删除完了元素之后先++了pos,因为删除的本质就是将删除位置的元素后面的所有元素统一往前移动一格位置,就会导致要删除的位置的元素被删除之后,要删除的元素的下一个元素就自动的移动到了要删除的元素的位置上,但是我们仍然++pos,就会导致删除的元素的下一个元素被无意间跳过,这就导致了要删除的元素的下一个元素永远无法删除,这便是这种情景没有完全删除所有的偶数元素的原因。 

在这三种情形下迭代器都已经失效了,那么我们该怎样去进行代码的修改呢?直接代码:

iterator  erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);

			iterator begin = pos;
			while (begin < _finish - 1)
			{
				*begin = *(begin + 1);
				begin++;
			}
			--_finish;
			//这里要返回pos位置上的数据,是因为,可能会跳过元素,这里有几种情况,所以我们必须返回删除之后,正确的迭代器的位置,所以我们要返回pos
			// 1 2 3 4 5 -> 正常
			// 1 2 3 4   -> 崩溃
			// 1 2 4 5   -> 没删除完
			return pos;
		}

这是删除元素的代码,我们用迭代器作为返回值的原因是因为,要返回删除的元素的下一个元素的位置,但是因为删除的思想,会导致要删除的元素后面的所有元素统一往前移动一个位置,所以要删除的元素的下一个元素的位置其实就是pos位置。 

原始版本:

void test1()
	{
		vector<int> v1;
		v1.pushback(1);
		v1.pushback(2);
		v1.pushback(4);
		v1.pushback(5);
	    vector<int>::iterator pos= v1.begin();
		while (pos != v1.end())
		{
			if (*pos % 2 == 0)
			{
				v1.erase(it);
			}

			++pos;
		}
	}

每次删掉元素都要进行迭代器的++,导致迭代器失效。 

改进版本:

void test1()
	{
		vector<int> v1;
		v1.pushback(1);
		v1.pushback(2);
		v1.pushback(4);
		v1.pushback(5);
		vector<int>::iterator pos =v1.begin();
		while (pos != v1.end())
		{
			if (*pos % 2 == 0)
			{
				pos = v1.erase(pos);
			}
			else
			{
				++pos;
			}
		}
	}
}

改进了之后,再删除掉元素之后,不直接++,而是返回要删除的元素的下一个元素的位置作为pos迭代器的值(采用这种方式的原因吗,其实还要为缩容去考虑,不然完全可以删除完之后不返回任何值)。 

编译器缩容场景的迭代器失效很少见到,所以我们就不做介绍。

本期内容到此结束^_^

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

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

相关文章

不知道如何批量处理图片

你是否曾经遇到过需要批量处理大量图片的情况&#xff1f;例如&#xff0c;需要将多张图片转换为统一格式、调整大小或进行美化处理。这种时候&#xff0c;如果一张张手动处理&#xff0c;不仅效率低下&#xff0c;还容易出错。那么&#xff0c;有没有一种方法可以快速、准确地…

web前端项目-动画特效【附源码】

文章目录 一&#xff1a;赛车游戏动画HTML源码&#xff1a;JS源码&#xff1a;CSS源码&#xff1a;&#xff08;1&#xff09;normalize.css&#xff08;2&#xff09;style.css 二&#xff1a;吉普车动画演示HTML源码&#xff1a;CSS源码&#xff1a;&#xff08;1&#xff09…

matlab对负数开立方根得到虚数的解决方案

问题描述&#xff1a;在matlab中&#xff0c;对负数开立方根&#xff0c;不出意外你将得到虚数。 例如 − 27 3 \sqrt[3]{-27} 3−27 ​&#xff0c;我们知道其实数解是-3&#xff0c;但在matlab中的计算结果如下&#xff1a; 问题原因&#xff1a;matlab中的立方根运算是在…

仅使用 Python 创建的 Web 应用程序(前端版本)第08章_商品详细

在本章中,我们将实现一个产品详细信息页面。 完成后的图像如下。 Model、MockDB、Service都是在产品列表页实现的,所以创建步骤如下。 No分类内容1Page定义PageId并创建继承自BasePage的页面类2Application将页面 ID 和页面类对添加到 MultiPageApp 的页面中Page:定义PageI…

项目管理平台

技术架构&#xff1a; MySQL、Servlet、JSP 功能模块&#xff1a; 从管理员角度看: 用户登入系统后&#xff0c;可以修改管理员的密码。同时具有以下功能&#xff1a; 1、管理员可以管理具体项目信息。 2、管理员可以管理项目经费信息。 3、管理员可以管理项目资源信息。 4、…

确定软件项目范围基准 5个重点

软件项目范围基准明确了项目的边界、目标和主要交付成果&#xff0c;有助于提高项目成本、进度和资源估算的准确性&#xff0c;便于实施项目控制&#xff0c;而且还可以帮助我们清楚分派责任&#xff0c;防止范围蔓延&#xff0c;从而提升项目的成功率。 如果没有明确确定范围基…

Hive实战 —— 电商数据分析(全流程详解 真实数据)

目录 前言需求概述数据清洗数据分析一、前期准备二、项目1. 数据准备和了解2.确定数据粒度和有效列3.HDFS创建用于上传数据的目录4.建库数仓分层 5.建表5.1近源层建表5.2. 明细层建表为什么要构建时间维度表&#xff1f;如何构建时间维度表&#xff1f; 5.3 轻聚层建表6. 指标数…

transformer架构的理解

一、transformer 架构 如上图所示&#xff0c;transformer&#xff08;形状像变压器&#xff1f;或者翻译成变形金刚&#xff0c;由不同模块拼装而成&#xff09;的架构左边是n个结构体相同的编码器&#xff08;例如&#xff0c;原论文是6个编码器的串联&#xff09;&#xff0…

第6章 python深度学习—第6章(波斯美女)

第6章 深度学习用于文本和序列 6.1 处理文本数据 与其他所有神经网络一样&#xff0c;深度学习模型不会接收原始文本作为输入&#xff0c;它只能处理数值张量。 文本向量化&#xff08;vectorize&#xff09;是指将文本转换为数值张量的过程。它有多种实现方法。 将文本分割…

迪文串口屏文本显示的使用

一、使用背景 由于迪文屏的数据变量显示功能不能显示字母类等字符&#xff0c;比如屏幕上要显示期日时间格式为2024-1-27 11:22:20&#xff0c;则不适合用数据变量显示&#xff0c;此时可以使用文本显示功能。 二、实现过程 1、首先查看迪文屏的使用手册DGUSII 应用开发指南…

两个近期的计算机领域国际学术会议(软件工程、计算机安全):欢迎投稿

近期&#xff0c;受邀担任两个国际学术会议的Special session共同主席及程序委员会成员&#xff08;TPC member&#xff09;&#xff0c;欢迎广大学界同行踊跃投稿&#xff0c;分享最新研究成果。期待这个夏天能够在夏威夷檀香山或者加利福尼亚圣荷西与各位学者深入交流。 SERA…

【投稿优惠|EI优质会议】2024年材料化学与清洁能源国际学术会议(IACMCCE 2024)

【投稿优惠|优质会议】2024年材料化学与清洁能源国际学术会议(IACMCCE 2024) 2024 International Conference Environmental Engineering and Mechatronics Integration(ICEEMI 2024) 一、【会议简介】 随着全球能源需求的不断增长&#xff0c;清洁能源的研究与应用成为了国际…

【leetcode题解C++】144. 94. 145.二叉树前序、中序、后序遍历 and 102.二叉树的层序遍历

144. 二叉树前序遍历 给出一个根节点&#xff0c;返回前中后序遍历的结果的。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root…

vue3 npm i 一直卡到不动

一. 首先node 版本要18.0及以上 查看node版本并安装指定版本 二. 查看npm镜像源以及指定安装npm的镜像 三. 删除项目中的package-lock.json文件 最好是把node_modules安装包也删除掉&#xff0c;然后npm i 就可以了

js打地鼠

文章目录 1实现效果2代码实现 1实现效果 游戏难度&#xff1a;简单&#xff0c;一般&#xff0c;困难&#xff0c;噩梦&#xff08;控制setInterval的time参数&#xff09; 按钮功能&#xff1a;结束&#xff08;可以通过修改gameScore的值来修改判定结束的分数&#xff09;&am…

python-自动化篇-办公-excel-实例应用(一维转二维)

文章目录 准备代码效果 准备 放根目录 代码 import openpyxl wbopenpyxl.load_workbook(业绩表.xlsx) if not 二维表 in wb.sheetnames:nwswb.create_sheet(二维表)wswb.worksheets[0]rngslist(ws.values)[1:]mmlist({m.value: for m in ws[b][1:]})namelist({m.value: for …

语义分割(3):损失函数解析

文章目录 1. 常见语义分割损失1.1 Cross Entropy1.2 dice Loss1.2.1 为什么使用Dice loss1.2.2 公式1.2.3 Dice loss 和 F1-score代码 1.3 focal loss1.3.1 公式&#xff1a;1.3.2 代码 2. 语义分割损失应用参考 语义分割任务实际上是一种像素层面上的分类&#xff0c;需要识别…

NPDP认证:产品经理的国际专业认证

你是否想证明自己在产品开发与管理方面的专业能力&#xff1f;NPDP认证正是你需要的&#xff01;&#x1f525; NPDP认证&#xff0c;即产品经理国际资格认证&#xff0c;由美国产品开发与管理协会&#xff08;PDMA&#xff09;所发起&#xff0c;是全球公认的新产品开发专业认…

Vulnhub靶机:FunBox 8

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;FunBox 8&#xff08;10.0.2.38&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/funb…

第3章-python深度学习——(波斯美女)

第3章 神经网络入门 本章包括以下内容&#xff1a; 神经网络的核心组件 Keras 简介 建立深度学习工作站 使用神经网络解决基本的分类问题与回归问题 本章的目的是让你开始用神经网络来解决实际问题。你将进一步巩固在第 2 章第一个示例中学到的知识&#xff0c;还会将学到的…