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程序启动代码的深入分析

    基于C程序启动代码的深入分析

    本篇文章是对C程序启动的代码进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 利用c++和easyx图形库做一个低配版扫雷游戏

    利用c++和easyx图形库做一个低配版扫雷游戏

    这篇文章主要介绍了用c++和easyx图形库做一个低配版扫雷游戏,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • C语言之初始if语句详解

    C语言之初始if语句详解

    本文主要介绍C语言中的if语句,这里详细介绍了if 语句并提供了简单的示例代码,希望能帮助编程入门的小伙伴学习,希望能够给你带来帮助
    2021-08-08
  • Qt自定义控件实现线条型加载条

    Qt自定义控件实现线条型加载条

    这篇文章主要为大家详细介绍了Qt自定义控件实现线条型加载条,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • 详解C++之函数重载

    详解C++之函数重载

    这篇文章主要介绍了c++函数重载的相关知识,文章讲解的非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • 详解C语言之动态内存管理

    详解C语言之动态内存管理

    本文主要介绍了C语言动态内存管理的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • c++ 完备的运行时类型信息(动态类型信息)

    c++ 完备的运行时类型信息(动态类型信息)

    这篇文章主要介绍了c++ 完备的运行时类型信息,需要的朋友可以参考下
    2017-07-07
  • C语言double和float 实例分析

    C语言double和float 实例分析

    本文主要介绍了C语言中的浮点数(float,double),并通过实例代码进行分析比较,希望能帮助学习相关知识的同学
    2016-07-07
  • 编辑器写C语言输出中文乱码问题及解决

    编辑器写C语言输出中文乱码问题及解决

    这篇文章主要介绍了编辑器写C语言输出中文乱码问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • C语言fillpoly函数详解

    C语言fillpoly函数详解

    在C语言中,fillpoly函数的功能是画一个多边形,并且把多边形填充。填充边框所定义的多边形的内部。fillpoly 函数的用法:void far fillpoly(int numpoints, int far *polypoints);。
    2015-10-10

最新评论