vector【实现】:迭代器失效以及非法的间接寻址、深拷贝中的浅拷贝。

news2024/11/28 0:56:16

 vector模拟实现_云的小站的博客-CSDN博客


目录

主题:

迭代器失效

Insert导致的迭代器失效

ereas导致的迭代器失效

非法的间接寻址

深拷贝中的浅拷贝。


主题:

1)迭代器失效

2)非法的间接寻址

3)深拷贝中的浅拷贝

迭代器失效

什么是迭代器失效,在vector里我们的迭代器其实就是指针

	template<class Ty>
	class vector
	{
	public:
		typedef Ty val_type;
		typedef val_type* iterator;

        //.....

所以在vector的迭代器失效其实是发生了野指针的问题。

失效发生常发生在Insert与ereas对pos的多次访问中。

Insert导致的迭代器失效

代码bug不考虑

 

这是STL库里面的vector的报错


我们自己实现的(9条消息) vector模拟实现_云的小站的博客-CSDN博客


发现第二次使用insert插入数据的时候,无论是库还是自己实现都不被允许,这是为什么呢,干嘛调试观察代码

插入前pos地址在d的有效数据范围内(start~finish)

插入后pos位置未改变,但是d的数据存放的位置改变。所以这个时候在下一次的Insert将失败 

看看库里的流程

 

 pos也成为了野指针,为什么呢?

        在vector扩容都是异地扩容,当Insert后原来的空间被释放,而pos指向的为原来的空间,当第一次Insert内发生了扩容,形参pos改变插入了数据,但是实参pos不被修改。第二次Insert插入时检测出了pos为野指针报错。就算不报错,我们的插入操作也是失效的。扩容导致的迭代器失效。

ereas导致的迭代器失效

那么ereas没有扩容为什么也会迭代器失效呢??有的STL实现在删除操作时,会调用缩容的操作,当缩容后就会导致pos位置失效。但是一般不会做缩容的操作,我们知道就好。

但是ereas的失效主要体现在使用中,

题目:删除数组中的偶数。

乍一看没什么问题但是数据一旦改变!

进程崩溃:

结果错误:

为什么呢?

崩溃原因是,it超出范围。

数组1  2  3  4  

将2删除,然后it++

将4删除  戏剧性的一幕发生了,

                                                                           原本it现在改于end()比较了,但是我们的it

                                                                          必须先++后比较,避开了循环结束条件。 

   这时候【】是end的位置,it完美错过结束判断。导致了it下一次在ereas的非法访问。

		while (it != d.end())//这里的it>end().

 结果错误原因:删除后出现一次跳过。

将删除数据2

++it(未判断移动到当前位置的数据

                                                                               就贸然it++,忽略了it当前的数据是否需要删除)

 结果有误!!!!。

结论:如果最后数据为删除程序崩溃,如果两个偶数连在一起,程序结果有误。

而12345的数据数组,恰好避开了2种错误。

那怎么才能对呢??

接收ereas返回值重新定义it值,it自增需要条件。vector::ereas在库中实现返回删除位置的下一个数据,在vector中其实就是返回pos的位置

 代码改为。

while (it != d.end())
{
	if (*it % 2 == 0)
	{
		it = d.ereas(it);
	}
	else 
	{
		++it;
	}
}

这样我们的结果都可以正确了

 

 结果都是正确的。


对于迭代器失效的问题的根本解决方案就是:不要多次直接使用pos数据!!未改变的pos只能用一次!!

非法的间接寻址

讲一个故事:你手上有一个香蕉,有2只猴子,怎么在不破坏香蕉的情况下,2只猴子都有香蕉吃?

答案是:再去摘一根香蕉......


我们实现构造函数中的一种重载函数:使用N个type初始化对象。

vector(size_type n, const Ty&val= Ty());

但是还有个重载的构造函数

template <class InputIterator>//可以是其他容器的迭代器
vector(InputIterator begin, InputIterator end)

如果我们这样创建vector对象

vector<int> d1(5, 6);
//报错!!: error C2100: 非法的间接寻址

为什么呢?编译器误调用了vector(InputIterator begin, InputIterator end);

这不是迭代器调用吗?虽然说明是迭代器的构造,但是这是模板函数,int,int也可以调用该函数,导致了,编译器误把对int类型数据解引用,操作错误!!

如何修改呢??我们不可以改变vector(size_type n, const Ty&val= Ty());的数据,但是我们可以重载一个int n,const...的构造函数

vector(size_type n, const Ty&val= Ty());
vector(int n, const Ty&val= Ty());      //重载size_t n,
//vector(long long n, const Ty&val= Ty());//重载size_t n,int n

这样编译器就会调用int n的函数,而不是调用迭代器构造函数。我们不改变size_t n  但是我们重载了int  n 的函数。


深拷贝中的浅拷贝。

深拷贝是深拷贝,浅拷贝是浅拷贝,什么是深拷贝中的浅拷贝???
二维数组的普通拷贝其实就是深拷贝的浅拷贝

三幅图理解!! 

浅拷贝

 这是二维数组的浅拷贝,直接拷贝了src中的地址。


 深拷贝的浅拷贝

我们将二维数组拷贝了一份给des,但是二维数组里面的一维数组地址,我们只是浅拷贝,拷贝了src二维数组中的地址值,而没有根据这些地址值,去拷贝所对应的一维数组。


  深拷贝的深拷贝

 深拷贝二维数组,本且根据原二维数组中的多个一维数组进行深拷贝。

所以我们在实现vector的拷贝逻辑时的reverse与拷贝构造,不可以使用mem*函数进行字节拷贝,而需要自己实现拷贝逻辑

		//1
		vector(const vector<val_type>&src)
		{
			_start = new val_type[src.capacity()];//也可以src.size(),二维数组时的第一层数组开辟空间
			//memmove(_start, src._start, sizeof(size_type) * src.size());
			// 自定义类型会极可能报错!!!
			for (size_t i = 0; i < src.size(); ++i)
			{
				_start[i] = src._start[i];//如果是自定义成员,会调用他的赋值拷贝,再次进行深拷贝!!!! 
				//而普通内置类型也不会发生错误,完成赋值拷贝
			}
			_finish = _start + src.size();
			_end_of_storage = _start+src.capacity();//和上面同步
		}

这里的“=”如果左右是自定义类型,就会调用他的赋值重载函数,如果是内置类型,就是编译器的事情了


ps:无论什么样的指针,内置类型指针,自定义类型指针,都属于内置类型!!(都是指针)

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

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

相关文章

2023年最佳SleekFlow最佳替代品

建立更强大的对话关系的最佳平台是什么&#xff1f;现如今&#xff0c;国内客服集成与营销自动化工具也有非常多&#xff0c;比如SaleSmartly&#xff08;ss客服&#xff09;&#xff0c;被称为SleekFlow的最佳替代品。了解为什么SaleSmartly是SleekFlow的最佳替代品。在这篇文…

BTC交易费激增,LTC活跃地址数飙升! BRC-20爆火背后,区块链网络经历了什么?

BRC-20 代币和 Ordinals 协议的日益普及推动了对比特币区块空间的需求&#xff0c;比特币区块链的费用已飙升至两年来的高点。 BRC-20代币标准在 Ordinals 协议上运行。Ordinals 允许用户通过将对数字艺术的引用写入基于比特币的小型交易中&#xff0c;来将数据嵌入比特币区块…

网站历史快照查询软件-批量网站历史快照查询

批量网站历史快照查询软件 批量网站历史快照查询软件是一种可以让用户在短时间内批量查询多个网站历史快照的工具&#xff0c;可以极大地提高用户的工作效率。批量实时查询是该软件的一大优势&#xff0c;下面主要介绍批量实时查询的优势。 一、高效性 批量实时查询可以同时…

通过2种Python库,教会你如何在自动化测试时加入进度条?

前言 我们在执行自动化测试或者调试时&#xff0c;自动化测试用例数量过多&#xff0c;不清楚目前用例数执行了多少个了&#xff0c;还差多少个执行完成。 这时候就会猜想&#xff0c;如果执行过程中存在进度条&#xff0c;就很清楚的了解到测试用例的执行情况&#xff0c;今…

Cannot read properties of null (reading ‘content‘)报错解决

项目是用vue3webpack&#xff0c;始终启动不成功~ 一、问题报错 二、报错解决尝试总结 &#xff08;1&#xff09;首先尝试的是因为我近期在做vite3vue3的需求把node版本升到了 16.17.1 猜测是不是node版本影响的 node版本切了14.15.3&#xff0c;16.17.1&#xff0c;以及很…

【换根DP+容斥】P3047 [USACO12FEB]Nearby Cows G

P3047 [USACO12FEB]Nearby Cows G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意&#xff1a; 思路&#xff1a; 做法就是换根 预处理dp[v][j]用普通的树形DP处理即可 注意&#xff1a;一开始预处理的dp[v][j]指的是在v的子树里离v为j的权值和 Code&#xff1a; #in…

JavaWeb12-三大组件之过滤器-Filter

1. 官方文档 文档&#xff1a;java_ee_api_中英文对照版.chm 2. Filter 过滤器说明 2.1 为啥要过滤器-需求示意图 ● 一图胜千言 2.2 过滤器介绍 Filter 过滤器它是 JavaWeb 的三大组件之一(Servlet 程序、Listener 监听器、Filter 过滤器)Filter 过滤器是 JavaEE 的规范…

图像处理:手写实现图像增广算法(旋转、亮度调整、裁剪与拼接)

前言 图像增广算法在计算机视觉领域扮演着至关重要的角色。随着深度学习的兴起&#xff0c;大规模数据集的需求变得更加迫切&#xff0c;而图像增广算法可以通过对原始图像进行一系列变换&#xff0c;扩充数据集&#xff0c;从而提升模型的泛化能力和鲁棒性。 本文将着重介绍…

win10系统cpu版本 Tensorflow2.5.0的安装

文章目录 前言电脑重装系统了&#xff0c;顺便简单记录一下我的tensorflow2.5.0 CPU的安装过程 一、创建一个虚拟环境&#xff1f;二、确定 输入 y三、激活你的环境四、安装tensorflow2.5.0五、利用清华镜像源加速一下&#xff0c;不然等到猴年马月&#xff01;六&#xff0c;开…

Shape-E:文字到3D的生成模型试用

文章目录 Shape-E&#xff1a;文字到3D的生成模型试用项目介绍项目地址项目使用试用Text to 3DImage to 3D 总结 Shape-E&#xff1a;文字到3D的生成模型试用 项目介绍 Shape-E是一个生成3D模型的工具&#xff0c;可以通过输入文字或者上传图片生成3D模型。该模型的项目地址是…

穿越火线(CF) AI 自瞄 代码 权重 数据集 亲测可用(结尾有资源)

初衷 本人热衷玩CF&#xff0c;同时为一名程序员&#xff0c;近期听说AI霸占FPS游戏&#xff0c;本着学习的态度&#xff0c;特来测试 不喜欢看过程的小伙伴直接看最下面 模型 采用yolov5模型架构 对过程感兴趣的小伙伴下文自行学习 https://zhuanlan.zhihu.com/p/17212138…

数字孪生技术在矿业领域怎样应用?

随着科技的不断发展&#xff0c;数字孪生技术正逐渐走入矿业领域&#xff0c;为这个传统行业带来了全新的变革和机遇。数字孪生技术以其精准模拟和实时监控的特性&#xff0c;为矿业企业提供了更高效、更安全的运营和管理方式。 在矿业开采过程中&#xff0c;数字孪生技术的应…

代码随想录算法训练营day42 | 01背包问题,你该了解这些!,01背包问题,你该了解这些! 滚动数组 , 416. 分割等和子集

代码随想录算法训练营day42 | 背包理论基础&#xff0c;背包理论基础&#xff08;滚动数组&#xff09;&#xff0c; 416. 分割等和子集 1、01背包理论基础背包问题概述01背包二维dp数组01背包案例 2、01背包理论基础&#xff08;滚动数组&#xff09;3、 416. 分割等和子集解…

Redis持久化-Redis主从-Redis哨兵-Redis分片集群

主要内容 Redis持久化Redis主从Redis哨兵Redis分片集群 Redis持久化 Redis有两种持久化的方案: RDB持久化AOF持久化 1. RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所…

数字化时代下,制造业企业应该这样做仓库管理

透过现象看本质&#xff0c;在传统的仓储管理中都存在着以下问题&#xff1a; 1.信息化水平较低&#xff0c;以人工为主&#xff0c;以纸张为主&#xff0c;效率低下&#xff0c;容易出现错误&#xff1b; 2.信息流的不对称性&#xff0c;各个过程之间的联系不紧密&#xff0c;…

【高危】Apache Spark UI shell 命令注入漏洞(POC)

漏洞描述 该漏洞是针对此前CVE-2022-33891漏洞的修订&#xff0c;原有漏洞通告中认为3.1.3版本已修复该漏洞&#xff0c;后发现仍受到影响&#xff0c;3.1.3版本已不再维护&#xff0c;官方建议升级至3.4.0版本。 Apache Spark是美国阿帕奇&#xff08;Apache&#xff09;软件…

在这里总有一款高温介电温谱仪适合您(GWJDN-300/600/1000型多种可选)

GWJDN-300型多用途型高温介电温谱仪 关键词&#xff1a;高温介电&#xff0c;变温&#xff0c;电容&#xff0c;损耗 GWJDN-300高温介电温谱仪是一款专门用于评估电介质材料高温介电机制&#xff08;材料极化、储能、驰豫、相变、微结构变化、分子团重新取向等&#xff09;的…

远程控制电脑怎么弄? 远程控制电脑方法介绍

如何免费远程控制电脑&#xff1f; “你好&#xff0c;你知道任何可靠的免费Windows远程控制软件吗&#xff1f;我需要在工作电脑和家用电脑之间进行远程控制&#xff0c;因为我将出差数周。有什么好用的远程控制电脑方法吗&#xff1f;提前致谢&#xff01;” 电脑之间如何…

ChatGPT学习指南

主旨 大家好&#xff0c;我是五竹。心血来潮整理了这份手册并且将为小白们持续更新和GPT相关的资源和教程&#xff0c;专注于打造一部最好的GPT入门指南。此文档永久免费在线查看&#xff0c;欢迎大家转发、收藏、点赞支持&#xff01;后面会在文档中更新&#xff1a;ChatGPT学…

优秀互联网产品经理必备的10张业务图谱

作为离产品最近的人&#xff0c;产品经理是团队的交通枢纽&#xff0c;链接运营的需求和程序员的开发工作。面对庞杂多面的工作&#xff0c;今天小编和大家聊聊产品经理在工作各环节想要精进专业&#xff0c;都需要具备哪些能力。 01学习篇 持续学习的概念早已被大家接受&#…