处理顺序容器迭代器失效问题

编写改变容器的循环程序

添加/删除vector、string或deque元素的循环程序必须考虑迭代器、引用和指针可能失效的问题。程序必须保证每个循环步中都更新迭代器、引用或指针。如果循环中调用的是insert或erase,那么更新迭代器很容易。这些函数都会返回一个有效的迭代器,使用其可以对迭代器进行更新。

//删除偶数元素,复制奇数元素
	vector<int> v = { 0,1,2,3,4,5,6,7,8,9 };
	auto it = v.begin();
	while (it != v.end()) {
		if (*it % 2) {
			it = v.insert(it, *it);//复制当前元素
			it += 2;//向前移动迭代器,跳过当前元素和插入到它之前的元素
		}
		else {
			it = v.erase(it);//删除元素,erase返回删除元素之后的元素
		}
	}

对于上述程序,调用erase后,不必递增迭代器,因为erase返回的是指向下一个元素的迭代器。调用insert后,insert返回指向新插入元素的迭代器。
在这里插入图片描述

不要保存end返回的迭代器

当添加/删除vector或string的元素后,或是在deque首元素外的任何位置添加/删除元素后,end返回的迭代器总会失效。因此,添加或删除元素的循环程序必须反复调用end()而不能在循环前将end返回的迭代器保存并一直当作容器末尾使用。

例如,如下程序希望实现功能:在容器中的每个元素后添加一个新元素。我们希望循环能够跳过新添加的元素,只处理原有元素。在每步循环后,定位迭代器使其指向下一个原有元素。如果我们试图在循环前保存end返回的迭代器,就会导致灾难:

	auto begin = v.begin();
	auto end = v.end();
	while (begin != end) {
		++begin;//向前移动begin,以在此元素后插入元素
		begin = v.insert(begin, 42);
		++begin;//跳过刚刚插入的元素
	}

此代码行为是未定义的。在VS2019中程序检测到迭代器不匹配而终止。在这里插入图片描述
必须在每次插入操作后重新调用end(),而不能在循环前保存它返回的迭代器

 //while (begin != end) {
    while (begin != end.()) {
		++begin;//向前移动begin,以在此元素后插入元素
		begin = v.insert(begin, 42);
		++begin;//跳过刚刚插入的元素
	}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值