C++ vector迭代器失效

STL中vector迭代器失效常见错误写法示例

最近在看STL容器失效的例子,涉及到vector数组迭代器失效的问题,如果不注意使用,很容易出现问题,我们先来看一下一个简单的示例程序,在数组nums中删除大于50的元素,代码如下:

#include <vector>
#include <iostream>

int main()
{
	std::vector<int> nums = { 15, 25, 8, 45, 78, 90, 125 };
	for (auto iter = nums.begin(); iter != nums.end();) {
		if (*iter > 50) {
			nums.erase(iter);	// 此处在删除iter之后iter迭代器失效,再在后续的for循环中使用iter进行!=运算时会导致崩溃
		} else {
			iter++;
		}
	}

	for (auto num : nums) {
		std::cout << num << std::endl;
	}

	std::cin.get();

	return 0;
}

在Visual Studio中运行上述程序后,会导致程序崩溃,截图如下:
运行崩溃
错误为:vector iterators incompatible,即向量迭代器不兼容
下面我们来看一下崩溃时的堆栈:
崩溃堆栈
程序崩溃了
!=判断运算符出问题
从上面堆栈可以看出,在iter != nums.end()进行判断时,由于iter迭代器已经失效了,此时再通过iter迭代器和nums.end()进行!=运算时,就出现崩溃了。
vector迭代器操作报错

正确的用法

首先我们来看一下正确的写法,代码如下:

#include <vector>
#include <iostream>

int main()
{
	std::vector<int> nums = { 15, 25, 8, 45, 78, 90, 125 };
	for (auto iter = nums.begin(); iter != nums.end();) {
		if (*iter > 50) {
			//nums.erase(iter);	// 此处在删除iter之后iter迭代器失效,再在后续的for循环中使用iter进行!=运算时会导致崩溃
			iter = nums.erase(iter);
		} else {
			iter++;
		}
	}

	for (auto num : nums) {
		std::cout << num << std::endl;
	}

	std::cin.get();

	return 0;
}

程序运行结果如下:
正确的写法运行结果
可以看到将之前代码的第9行的nums.erase(iter); 语句改成iter = nums.erase(iter);就能正常删除vector数组中大于50的数了。这是因为vector数组在对某个iter迭代器执行erase操作之后会返回一个后向迭代器。而且vector是顺序容器,直接对nums.erase(iter)操作之后,iter本身以及其后的元素都会挪动位置了。但是nums.erase(iter)会返回一个正确的后序迭代器,将其赋值给iter,再对iter进行操作就OK了。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值