当前位置: 首页 > article >正文

【C++】有关vector迭代器失效问题

在这里插入图片描述
个人主页
在这里插入图片描述

文章目录

  • 一、迭代器失效是什么
  • 二、vector中哪些操作会导致迭代器失效
  • 三、如何避免迭代器失效的问题

一、迭代器失效是什么

在进入此问题时,我们首先要了解迭代器的本质其实是指针,迭代器的失效就相当于指针失效的问题。而指针失效就说明指针指向的空间是非法的,变成为了野指针。
空间非法: 就是指指针指向了已经被释放的空间或者越界访问,
我们可以用代码的方式来解释此问题。

#include<iostream>
#include<vector>
using namespace std;
void test()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	auto it = v.begin();
	v.push_back(5);
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

通过上述代码,当我们运行程序时会发生报错。其原因就是因为迭代器失效的问题。我们可以分析一下其中的过程。

过程:it一开始指向初始空间的元素,而再次进行尾插操作时,由于空间不够需要扩容,因此需要释放旧空间开辟新空间,但此时的it还是指向已经被释放的旧空间,已经成为野指针了,因此再循环当中对野指针进行解引用是就会导致程序崩溃。

二、vector中哪些操作会导致迭代器失效

在所有可能对空间进行扩容操作的都有可能导致迭代器失效,如:push_back、resize、insert、reserve等。

需要注意的是:有一个特殊的操作,编译器也会认为迭代器失效,就是erase操作。
我们要知道,erase函数的返回值是返回被删除元素的后一个位置,当删除完元素时,当前位置之后的元素都会往前进行偏移,但这并没有导致空间的改变,理论上这是不是并没有导致迭代器失效呢?

那么如果当前位置的元素刚好就是最后一个元素时,当对其进行删除时,返回的位置则指向end(),而end()的位置并没有元素,那么当对其进行解引用时也会导致程序崩溃,因此编译器认为这样的操作并不安全,于是认为当删除完元素时,迭代器就应该按失效的方式处理,不再对其进行使用。

#include<iostream>
#include<vector>
using namespace std;
void test()
{
	vector<int> v{1,2,3,4,5,6};
	auto it = v.begin();
	//删除偶数
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			v.erase(it);
		}
		else
		{
			it++;
		}
	}
}

三、如何避免迭代器失效的问题

通过以上叙述,我们了解了有关迭代器失效的产生及问题,那么我们该如何避免此问题发生呢?
其实解决办法也挺简单的:只需当我们使用了有可能对迭代器失效的操作时,如果想再次使用迭代器时,只需在使用前令其指向新空间。

我们可以用一段代码来演示过程:
举例:使用push_back函数

#include<iostream>
#include<vector>
using namespace std;
void test()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	auto it = v.begin();
	v.push_back(5);
	it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

通过上述代码,当我们要再次进行尾插操作时,只需改变一下it指向新空间的位置即可,这样就不会导致迭代器产生失效的问题了。


http://www.kler.cn/a/284804.html

相关文章:

  • GIS空间分析案例---城市公共设施配置与服务评价
  • K8资源之endpoint资源EP资源
  • qt QVideoWidget详解
  • GEE 数据集——美国gNATSGO(网格化国家土壤调查地理数据库)完整覆盖了美国所有地区和岛屿领土的最佳可用土壤信息
  • AcWing 300 任务安排1
  • 《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>
  • 快速了解Git服务器端基础及基本操作命令(一)
  • mysql的group by怎么用
  • disk manager操作教程 如何使用Disk Manager组件 Mac如何打开ntfs格式文件
  • Open WebUI官方库:解锁人工智能服务的官方通道
  • git常见命令行及分支规范
  • MATLAB智能优化算法-学习笔记(1)——遗传算法求解0-1背包问题【过程+代码】
  • 通过css,js html结合实现第一个页面
  • 网络安全实训六(靶机实例DC-3)
  • 迭代器模式
  • TWRP 使用帮助 第三方Recovery
  • 给鼠标一个好看的指针特效 鼠标光标如何修改形状?
  • 如何在项目中配置.gitignore文件
  • [合集]一汽大众(斯柯达、奥迪、兰博基尼、宾利等)故障代码查询合集
  • 【论文笔记】独属于CV的注意力机制CBAM-Convolutional Block Attention Module
  • Ubuntu上安装配置(jdk/tomcat/ufw防火墙/mysql)+mysql卸载
  • ssm面向企事业单位的项目申报小程序论文源码调试讲解
  • 大数据处理从零开始————1.Hadoop介绍
  • 50ETF期权合约要素有哪些?50ETF期权合约组成构成分享
  • MFC工控项目实例之九选择下拉菜单主界面文本框显示菜单名
  • Python算法工程师面试整理-Python 在算法中的应用