删除元素使迭代器失效

迭代器提供一种方法能够访问一个容器里面的数据,而又不用暴露该容器内部的表达式,设计思想是将数据容器和算法分开,然后利用迭代器这个粘合剂将他们撮合在一起。

迭代器的使用要注意失效问题。(erase返回被删除迭代器的下一个迭代器)

对于顺序容器的失效:
void test()
{
	vector v = { "aaaaaaaaaa", "bbbbbbbbbb", "ccccccccc", "dddddddd","eeeeeeeeeeeee" };
	vector::iterator it = v.begin();
	for (; it != v.end();)
	{
		if (*it == "ccccccccc")
			v.erase(it);
		else
			it++;
	}
}


例如这样对于vector,因为将“ccccccccc”删除后因为会发生崩溃的现象,因为vector是是顺序容器,删除它后“dddddddd“及后面的元素会立马向前移动,因为“ccccccccc"已经是一块被释放的空间,现在它已经是一块未知空间现在对它空间指派值会发生错误,因为没进行申请内存的动作。现在的做法让应该不使用这一块已经释放了得空间,所以对代码进行修改如下:
void test()
{
	vector v = { "aaaaaaaaaa", "bbbbbbbbbb", "ccccccccc", "dddddddd","eeeeeeeeeeeee" };
	vector::iterator it = v.begin();
	for (; it != v.end();)
	{
		if (*it == "ccccccccc")
			it=v.erase(it);
		else
			it++;
	}
}


对于非顺序容器的的失效:
void test()
{
	list l;
	l.push_back(1);
	l.push_back(3);
	l.push_back(5);
	l.push_back(7);

	list::iterator it = l.begin();
	for (; it != l.end();)
	{
		if (*it = 4)
		{
			l.erase(it);
		}
		else
			it++;
	}
}


因为list是一个双向链表,因为删除当前迭代器会使其找不到后面的节点,这样指针++后指向的是一块未知的空间,所以也会造成程序的崩溃。修改方式也是将erase的返回迭代器进行记录,直接就避免了对删除了那个节点进行++操作,这样就避免了崩溃。
修改后为:
void test()
{
	list l;
	l.push_back(1);
	l.push_back(3);
	l.push_back(5);
	l.push_back(7);

	list::iterator it = l.begin();
	for (; it != l.end();)
	{
		if (*it = 4)
		{
			it=l.erase(it);
		}
		else
			it++;
	}
}


你可能感兴趣的:(C++)