C++ vector迭代器失效

2023-11-26 09:38:37 浏览数 (3)

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

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

代码语言:javascript复制
#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,即向量迭代器不兼容, 下面我们来看一下崩溃时的堆栈:

正确的用法

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

代码语言:javascript复制
#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了。

0 人点赞