初夏小谈:vector中迭代器失效问题

在模拟vector中会发生一种错误,程序崩溃。经过调试发现当使用迭代器时当指向的空间发生扩容后,在对用迭代器指向的空间进行解引用时会发生程序崩溃。在vector中,我们知道迭代器可以看作是原生态的指针,那么对指针进行解应用发生崩溃,就说明了对一块不属于当前指针的空间进行了解引用。


在vector中使用迭代器发生崩溃会存在两种情况:

一、根据上面所说的情况就可以总结为:当容量发生改变时就有可能发生迭代器失效。例如(进行插入元素,增加有效元素个数,扩容时等等)可能引起另辟空间进行搬移数据就会产生迭代器失效的问题。

例子:

void TestVector5()
{
	vector<int> v{ 1,2,3,4,5 };
	for (auto& e : v)
	{
		cout << e << " ";
	}
	vector<int>::iterator it = v.begin();
	v.reserve(16);
	cout << *it << endl;
}

运行结果:

产生崩溃的原因就是:原来的空间进行扩容后,就在另一块内存上开辟了一片相应要求的空间并且将原来内存上的数据搬过去。但是it依旧是还是指向原来的空间上,原来的空间已经被释放。如果再次对it进行操作,就会崩溃,你想对释放的空间进行解引用吗?那是不可能的呵呵。

针对上述问题解决办法

就是因为迭代器的指向不能自动跟着变化所以就进行手动跟上对应空间。

void TestVector5()
{
	vector<int> v{ 1,2,3,4,5 };
	for (auto& e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	vector<int>::iterator it = v.begin();
	v.reserve(16);
	it = v.begin();
	cout << "*it = " << *it << endl;
}

运行结果:

二、第二种情况就是在对迭代器所指向的元素删除时(erase),就会崩溃

代码例子:

void TestVector6()
{
	vector<int> v{ 1,2,3,4,5 };
	for (auto& e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		v.erase(it);	
	}
}

结果显示:

这是因为:当删除第一个数据后,所有数据都往前移动一次。但是it虽然指向第二个元素。但是它依然去找寻已经删除第一个数据,显然不会找到,迭代器也太执着了。就发生崩溃。

解决办法:就是每删除一个数据,就重新将迭代器指向第一个位置。脱离已故的主人吧,该换新主人了。呵呵。

void TestVector6()
{
	vector<int> v{ 1,2,3,4,5 };
	for (auto& e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		//v.erase(it);	
		it = v.erase(it);
		for (auto& e : v)
		{
			cout << e << " ";
		}
		cout << endl;
	}
}

运行结果:

总结一下迭代器失效问题:本质指针,指针所指向的空间失效了,从而指针指向了一块非法的空间。

                                                                                                                                                                  珍&源码

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值