容器insert、erase操作引起迭代器失效问题

// insert、erase操作引起迭代器失效问题

#include "stdafx.h"
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>

using namespace std;

void print_list(const list<int>& l)
{
	list<int>::const_iterator it;
	for(it=l.begin(); it!=l.end(); ++it)
	{
		cout<<*it<<ends;
	}
	cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	// 迭代器失效问题的解决方式:
	// 确保传给insert、erase的迭代器在下次insert、erase操作时有效
	// 一般是将迭代器重置为insert、erase返回值(再适当++、--)或者重新计算迭代器
	int a1[] = { 1,2,3,4,5 };
	int a2[] = { 1,2,6,7,8 };
	list<int> list1(a1, a1+sizeof(a1)/sizeof(a1[0]));
	list<int> list2(a2, a2+sizeof(a2)/sizeof(a2[0]));

	// 删除list2中值属于list1的元素(1,2)
	list<int>::iterator it;
	for(it=list1.begin(); it!=list1.end(); ++it)
	{
		auto pos = find(list2.begin(), list2.end(), *it);
		if(pos != list2.end())
		{
			list2.erase(pos);
		}
	}
	print_list(list2);

	// 在list2中插入属于list1但不属于list2的值(3,4,5)
	for(it=list1.begin(); it!=list1.end(); ++it)
	{
		auto pos = find(list2.begin(), list2.end(), *it);
		if(pos == list2.end())
		{
			// 每次pos都被重新定义和计算,无需重置pos为返回值,虽然这次操作后当前pos失效
			list2.insert(pos, *it);
		}
	}
	print_list(list2);

	// 删除list2中值不属于list1的元素(6,7,8)
	for(it=list2.begin(); it!=list2.end(); )
	{
		auto pos = find(list1.begin(), list1.end(), *it);
		if(pos == list1.end())
		{
			// 注意迭代器失效问题,如果不保存it,it失效,则++it是未定义行为,
			// it值必须同时改变为返回值(删除之后的迭代器)
			it = list2.erase(it); 
		}
		else
			++it;
	}
	print_list(list2);

	// 在list2中插入一次性5个属于list1又属于list2的值(1,2,3,4,5)
	for(it=list1.begin(); it!=list1.end(); ++it)
	{
		auto pos = find(list2.begin(), list2.end(), *it);
		if(pos != list2.end())
		{
			for(int i=0; i<5; ++i)
			{
				// 注意迭代器失效问题,如果不保存pos,pos失效第二次插入时pos已经失效
				// 在pos之前插入,返回指向新元素的迭代器(pos-1)
				pos = list2.insert(pos, *it); 
				// 确保每次在相同位置插入:第一次的pos之前
				++pos;
				// ++pos; // error! pos指向将不定
			}
		}
	}
	print_list(list2);

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值