记录C++中,vector的迭代器在push_back以后扩容导致迭代器失效的问题

前言

        vector是我们用到最多的数据结构,其底层数据结构是单端动态数组,由于数组的特点,vector也具有以下特性: ①O(1)时间的快速访问; ②顺序存储,所以插入到非尾结点位置所需时间复杂度为O(n),删除也一样; ③扩容规则: 当我们新建一个vector的时候,会首先分配给他一片连续的内存空间,如std::vector vec,当通过push_back向其中增加元素时,如果初始分配空间已满,就会引起vector扩容,其扩容规则在gcc下以2倍方式完成:

  •         首先重新申请一个2倍大的内存空间;
  •         然后将原空间的内容拷贝过来;
  •         最后将原空间内容进行释放,将内存交还给操作系统;


注意事项:根据vector的插入和删除特性,以及扩容规则,我们在使用vector的时候要注意,在插入位置和删除位置之后的所有迭代器和指针引用都会失效,同理,扩容之后的所有迭代器指针和引用也都会失效。

原文链接:https://blog.csdn.net/qq_45311905/article/details/117020436

问题1:使用{}赋值,会丧失扩容功能

        vector的最原始大小是0,如果使用{}方法去赋值,那么会丧失扩容功能

#include <iostream>
#include <vector>

int main() {
	std::vector<int> numbers = {1, 2, 3, 4, 5};
	
	// 获取第二个元素的迭代器
	auto it = numbers.begin() + 1;
	
	// 在第二个位置插入一个新元素,导致vector扩容
	numbers.insert(numbers.begin() + 1, 10);
	
	// 尝试访问迭代器指向的元素,会导致未定义行为    会打印随机值
	std::cout << "Value at iterator: " << *it << std::endl;
	
	// 实际值:
	std::cout << "Value at iterator: " << numbers[1] << std::endl;
	
	return 0;
}

会发现打印随机值

如果不使用{}就没问题:

#include <iostream>
#include <vector>

int main() {
	std::vector<int> numbers;
	numbers.push_back(1);
	numbers.push_back(2);
	numbers.push_back(3);
	numbers.push_back(4);
	numbers.push_back(5);
	
	
	// 获取第二个元素的迭代器
	auto it = numbers.begin() + 1;
	
	// 在第二个位置插入一个新元素,导致vector扩容
	numbers.insert(numbers.begin() + 1, 10);
	
	// 尝试访问迭代器指向的元素,会导致未定义行为    会打印随机值
	std::cout << "Value at iterator: " << *it << std::endl;
	
	// 实际值:
	std::cout << "Value at iterator: " << numbers[1] << std::endl;
	
	return 0;
}

问题2:在push_back()以后,继续使用迭代器会触发扩容导致迭代器失效

#include <iostream>
#include <vector>

int main() {
	std::vector<int> numbers;
	
	size_t max_capacity = 0;
	
	
	max_capacity = numbers.capacity();
	std::cout<<"max:"<<max_capacity<<std::endl;		// 0
	
	// 第一次添加数据,会导致第一次扩容
	numbers.push_back(100);
	auto it = numbers.begin() + 0;
	std::cout<<"*it:"<<*it<<std::endl;
	std::cout<<"number[0]:"<<numbers[0]<<std::endl;
	std::cout<<std::endl;
	
	// 第二次添加数据,会导致第二次扩容,迭代器失效,下标法不会失效
	numbers.push_back(2);
	max_capacity = numbers.capacity();
	std::cout<<"max:"<<max_capacity<<std::endl;
	std::cout<<"*it:"<<*it<<std::endl;
	std::cout<<"number[0]:"<<numbers[0]<<std::endl;
	it = numbers.begin() + 0;
	std::cout<<"new *it:"<<*it<<std::endl;
	std::cout<<std::endl;
	
	// 第三次添加数据,会导致第三次扩容,但是发现迭代器并没有失效,下标法不会失效
	numbers.push_back(2);
	numbers.push_back(2);
	numbers.push_back(2);
	numbers.push_back(2);
	max_capacity = numbers.capacity();
	std::cout<<"max:"<<max_capacity<<std::endl;
	std::cout<<"*it:"<<*it<<std::endl;
	std::cout<<"number[0]:"<<numbers[0]<<std::endl;
	it = numbers.begin() + 0;
	std::cout<<"new *it:"<<*it<<std::endl;
	std::cout<<std::endl;
	
//  因为一种在增加,所以发现程序所占内存越来越大	
//	for (int i = 1; ; ++i) {
//		numbers.push_back(i);
//		if (numbers.size() > numbers.capacity()) {
//			max_capacity = numbers.size() - 1;
//			break;
//		}
//	}
	
	return 0;
}

        原因是,在最开始的时候,vector的容量是0,随着push-back,会不断 x2 的去增加容量,但是增加容量的时候,最开始获取的迭代器指针去获取数据的方式就失效了,不过好在使用下标并不会失效。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JDK21|史诗级的更新,虚拟线程

作者:鱼仔 博客首页: https://codeease.top 公众号:Java鱼仔 前言 要想看官方对于JDK21的更新说明&#xff0c;可以直接跳转到下面这个官方网站中 官网地址为&#xff1a;https://openjdk.org/projects/jdk/21/ JDK21是最新的LTS版本&#xff0c;里面添加了不少新的特性&…

中小型集群部署,Docker Swarm(集群)使用及部署应用介绍

1、Docker Swarm简介 说到集群&#xff0c;第一个想到的就是k8s&#xff0c;但docker官方也提供了集群和编排解决方案&#xff0c;它允许你将多个 Docker 主机连接在一起&#xff0c;形成一个“群集”&#xff08;Swarm&#xff09;&#xff0c;并可以在这个 Swarm 上运行和管…

【Web APIs】DOM节点

目录 1.节点操作 1.1DOM节点 1.2查找节点 1.2.1父节点查找 1.2.2子节点查找 1.2.3兄弟节点查找 1.3增加节点 1.4克隆节点 1.5删除节点 2.时间对象 2.1实例化 2.2时间对象方法 2.3时间戳 3.重绘和回流 1.节点操作 1.1DOM节点 DOM节点&#xff1a;DOM树中的每一个…

BaseDao封装增删改查

文章目录 什么是BaseDao操作代码增删改查询单个数据查询多个数据 总结 什么是BaseDao BaseDao是&#xff1a; 数据库里负责增加&#xff0c;删除&#xff0c;修改&#xff0c;查询 具体来说是一种接口代码,公共方法的接口类。 在dao层新建basedao,其他dao层接口继承basedao 相…

《VulnHub》Lampião:1

title: 《VulnHub》Lampio&#xff1a;1 date: 2024-03-28 21:37:49 updated: 2024-03-28 21:37:50 categories: WriteUp&#xff1a;Cyber-Range excerpt: 关键技术&#xff1a;主机发现&#xff0c;端口扫描、服务探测、操作系统探测&#xff0c;对开放的端口探测漏洞&#x…

正弦实时数据库(SinRTDB)的使用(5)-历史数据查询

前文已经将正弦实时数据库的使用进行了介绍&#xff0c;需要了解的可以先看下面的博客&#xff1a; 正弦实时数据库(SinRTDB)的安装 正弦实时数据库(SinRTDB)的使用(1)-使用数据发生器写入数据 正弦实时数据库(SinRTDB)的使用(2)-接入OPC DA的数据 正弦实时数据库(SinRTDB)…

民航电子数据库:查询cae服务存在哪些数据库以及删除数据库

目录 一、场景二、查询数据库列表三、删除数据库 一、场景 1、对接民航电子数据库 2、在CAEManage是没有直观展示已存在的数据库的&#xff0c;只能通过SQL查询 3、在CAEManage没有操作按钮可以删除数据库&#xff0c;只能通过SQL进行删除 二、查询数据库列表 1、登录SYSTE…

我是如何在学术界占有一席之地的——专注于我的写作

罗伯特纽贝克 “作为一个移民&#xff0c;你是怎么发表这么多文章的&#xff1f;”意识到我不是以英语为母语的人&#xff0c;当我去年面试教职时&#xff0c;人们无数次问过这个问题。我知道披露我的挣扎不太可能让我找到工作&#xff0c;所以我会笑着说&#xff1a;“我喜欢…

Xinstall广告效果监测,为您的App推广保驾护航

在当前的移动互联网时代&#xff0c;App已经成为企业与用户连接的重要桥梁。然而&#xff0c;App推广过程中&#xff0c;如何准确衡量广告效果、洞悉推广效果以及优化用户体验&#xff0c;一直是广告主和开发者面临的挑战。这时&#xff0c;一款强大而专业的App全渠道统计服务商…

蓝桥杯刷题第四天

思路&#xff1a; 这道题很容易即可发现就是简单的暴力即可完成题目&#xff0c;我们只需满足所有数的和为偶数即可保证有满足条件的分法&#xff0c;同时也不需要存下每个输入的数据&#xff0c;只需要知道他是偶数还是奇数即可&#xff0c;因为我们只需要偶数个奇数搭配在一块…

Manjaro 安装全新 Linux 版微信,从此告别 Wine

目前已经基本上使用 Manjaro 来工作&#xff0c;而工作离不开微信作为日常的工作沟通工具。因为微信官方一直没有 Linux 版本的&#xff0c;所以之前都只能够使用 Wine 版本&#xff0c;然后踩了不少坑&#xff0c;但还算能勉强使用。 最近听说微信终于要发布 Linux 版本的&am…

day22.二叉树part08

day22.二叉树part08 235.二叉搜索树的最近公共祖先 原题链接 代码随想录链接 思路&#xff1a;因为本题是二叉搜索树&#xff0c;利用它的特性可以从上往下进行递归遍历树&#xff0c;这里需要理解一点就是如果遍历到的一个节点发现该节点的值正好位于节点p和节点q的值中间…

ip地址改变导致nacos无法登录的解决方法

ip地址改变导致nacos无法登录的解决方法 在做黑马的springcloud课程里的黑马商城微服务项目时&#xff0c;发现使用nacos的默认账号密码&#xff08;nacos&#xff0c;nacos&#xff09;无法登录&#xff0c;项目里也没报错信息&#xff0c;虽然猜测和ip地址改变有关&#xff0…

视频素材免费无水印软件有哪些?视频素材免费下载素材库

在这个视觉为王的时代&#xff0c;一段精彩的视频能够跨越语言和文化的障碍&#xff0c;触动每一个心灵。对于每一位热血沸腾的视频创作者而言&#xff0c;寻找那些高质量无水印的素材&#xff0c;就像是在无尽的创意海洋中航行&#xff0c;在这段旅程中&#xff0c;我为你精选…

银行监管报送系统介绍(八):银行业大额交易和可疑交易报告数据报送

依据《金融机构大额交易和可疑交易报告管理办法》&#xff1a; 第五条 金融机构应当报告下列大额交易&#xff1a; &#xff08;一&#xff09;当日单笔或者累计交易人民币5万元以上&#xff08;含5万元&#xff09;、外币等值1万美元以上&#xff08;含1万美元&#xff09;的…

尾盘拉升超8个点,速腾聚创交出来一份怎样的超预期答卷?

“如果说2024年是智驾加速渗透&#xff0c;L3级智能驾驶陆续落地的一年&#xff0c;那么激光雷达将是这股潮流中不可缺失的那一份。” 2024年开年&#xff0c;速腾聚创以相当“闪亮的姿态”成为“港股2024年首只IPO上市成功”的企业。 然而&#xff0c;其上市之后的市场表现却…

Unity 渲染

渲染的三个阶段 1&#xff1a;应用阶段 1.1 数据的准备 遮挡剔除&#xff0c;层级剔除。 渲染顺序&#xff0c;UI在Herachy窗口按照层级渲染&#xff0c;其余物体由大概按照先近后远。 打包渲染数据发送给显存&#xff0c;主要包括有模型信息&#xff0c;变换矩阵&#xff0c…

《VideoMamba》论文笔记

原文链接&#xff1a; [2403.06977] VideoMamba: State Space Model for Efficient Video Understanding (arxiv.org) 原文笔记 What&#xff1a; VideoMamba: State Space Model for Efficient Video Understanding 作者探究Mamba模型能否用于VideoUnderStanding作者引入…

若依ruoyi-vue实现excel导入导出

文章目录 Excel注解excel数据导入前端实现后端实现 下载模板前端实现后端实现 excel数据导出前端实现后端实现 自定义标题信息导出用户管理表格新增标题&#xff08;用户列表&#xff09;导入表格包含标题处理方式 自定义数据处理器自定义隐藏属性列导入对象的子对象导出对象的…

6、父子组件传参、路由的嵌套、命名视图、路由跳转传参

一、父子组件传参 1、父传子 在父组件的子组件中自定义一个属性在子组件中有一个props属性&#xff0c;用来接收父组件传递的数据,传递的数据不能修改,还可以设置默认值 <!-- 父组件 -->data() {return {flag: false,num:10, //传的参数free:}} <!-- :type1"…