C++迭代器失效与预防

一 序列式容器

vector
数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,
所以,插入点和删除掉之后的迭代器全部失效,也就是说insert(*it )(或erase(*it )),然后在it ++,是没有意义的。
解决方法:erase(*it )的返回值是下一个有效迭代器的值。 it =cont.erase(it );或者it = vec.insert(it,0);

void vectorIter()
{
    
    
	vector<int> vec;
	for (int i = 0; i < 10; i++)
	{
    
    
		vec.push_back(i);//0,1,2,3,4,5,6,7,8,9
	}

	for (auto it = vec.begin(); it != vec.end(); it++)
	{
    
    
		if (*it == 5)
		{
    
    
			it =vec.erase(it);//删除5后迭代器指向6
			it = vec.insert(it,0);//插入0后迭代器指向0
			//直接erase或者insert会崩溃,因为迭代器失效了
		}
	}

	for (auto it = vec.begin(); it != vec.end(); it++)
	{
    
    
		cout << *it << endl;
	}

}

二 链表式容器

list
链表型数据结构:对于list型的数据结构,使用了不连续分配的内存
删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++);
插入数据不会失效迭代器

void listIter()
{
    
    
	list<int> lst;
	for (int i = 0; i < 10; i++)
	{
    
    
		lst.push_back(i);//0,1,2,3,4,5,6,7,8,9
	}

	for (auto it = lst.begin(); it != lst.end(); it++)
	{
    
    
		if (*it == 5)
		{
    
    
			//it = lst.erase(it);//删除5后迭代器指向6
			lst.erase(it++);		//同上面一个效果
	
		}
	}

	for (auto it = lst.begin(); it != lst.end(); it++)
	{
    
    
		cout << *it << endl;
	}

}

三 关联式容器

map
关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。

void mapIter()
{
    
    
	map<int, int> map;
	for (int i = 0; i < 10; i++)
	{
    
    
		map[i] = i;
	}

	for (auto it = map.begin(); it != map.end(); it++)
	{
    
    
		if ((*it).first ==5)
		{
    
    
			//map.erase(it++);//同下方一样
			it =map.erase(it);		
		}
	}
}

猜你喜欢

转载自blog.csdn.net/GreedySnaker/article/details/114967640