C++中vector迭代器失效问题的原因及解决方案

 更新时间:2024年09月05日 10:01:14   作者:夜晚中的人海  
迭代器(iterator)是一种用于遍历数据集合的的对象,它提供了一种访问数据集合中元素的方式,而无需暴露数据集合内部的细节,使用迭代器,我们可以对数据集合中的每个元素进行处理,本文介绍了C++中关于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指向新空间的位置即可,这样就不会导致迭代器产生失效的问题了。

到此这篇关于C++中vector迭代器失效问题的原因及解决方案的文章就介绍到这了,更多相关C++ vector迭代器失效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言Turbo C下实现俄罗斯方块

    C语言Turbo C下实现俄罗斯方块

    这篇文章主要为大家详细介绍了C语言Turbo C下写的俄罗斯方块,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • 详解C++二叉搜索树的原理及实现

    详解C++二叉搜索树的原理及实现

    二叉搜索树又称二叉排序树,二叉搜索树是一种二叉树,其中每个节点的值大于其左子树中的任何节点,并且小于其右子树中的任何节点,本文小编就给大家讲讲C++二叉搜索树的操作及实现,感兴趣的同学跟着小编一起来看看吧
    2023-08-08
  • Windows上CLion的配置步骤详解

    Windows上CLion的配置步骤详解

    这篇文章主要介绍了Windows上CLion的配置,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • C语言 联合(union)用法案例详解

    C语言 联合(union)用法案例详解

    这篇文章主要介绍了C语言 联合(union)用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 基于OpenCV读取摄像头实现单个人脸验证MFC程序

    基于OpenCV读取摄像头实现单个人脸验证MFC程序

    这篇文章主要为大家详细介绍了基于OpenCV读取摄像头实现单个人脸验证MFC程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • C++编写的WebSocket服务端客户端实现示例代码

    C++编写的WebSocket服务端客户端实现示例代码

    本文主要介绍了C++编写的WebSocket服务端客户端实现示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • c++和python实现顺序查找实例

    c++和python实现顺序查找实例

    这篇文章主要介绍了c++和python实现顺序查找实例,流程即将目标数值和数据库中的每个数值进行比较,如果相同则搜索完成,如果不同则继续比较下一处,下面来看看具体的实例操作吧,需要的朋友可以参考一下
    2022-03-03
  • 关于C/C++中static关键字的作用总结

    关于C/C++中static关键字的作用总结

    以下是对C/C++中static关键字的作用进行了总结介绍,需要的朋友可以过来参考下
    2013-09-09
  • C++求所有顶点之间的最短路径(用Dijkstra算法)

    C++求所有顶点之间的最短路径(用Dijkstra算法)

    这篇文章主要为大家详细介绍了C++用Dijkstra算法求所有顶点之间的最短路径,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C++调用Go方法的字符串传递问题及解决方案

    C++调用Go方法的字符串传递问题及解决方案

    这篇文章主要介绍了C++调用Go方法的字符串传递问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论