【C++】vector迭代器失效问题

vector迭代器失效问题

迭代器失效是什么
迭代器失效,是不能再去拿迭代器去访问vector中的元素,此时的迭代器指向的这块空间已经被释放了,也就是说此时的迭代器已经是野指针了。

insert 可能会导致迭代器失效

当vector数组开辟一段的空间之后,调用insert函数,向数组中插入一个值后,有可能会导致原来的空间不足,这时候,vector要进行深拷贝,就会开辟一个更大的空间,将原来空间上的数据拷贝到新开辟的空间上。但是此时你的迭代器还是指着旧空间上的一个位置,是一个野指针。所以这个迭代器就已经失效了。
迭代器失效insert是增容导致的失效,但是是可能失效。如果插入一个数据之后,原来的数组空间不进行增容,那么insert插入之后就不会失效。
所以,insert会导致迭代器增容,迭代增容有可能导致迭代器失效。主要取决于插入后vector是否增容

迭代器失效以后,我们就不能再次使用这个迭代器了,我们必须重新再次查找特定元素更新迭代器。

如下列程序:

int main()
{
	int a[] = {1,2,3,4};
	vector<int> v (a,a + sizeof(a)/sizeof(int));
	//指针是天然的迭代器,可以像迭代器一样使用

	vector<int>::iterator pos = find(v.begin(),v.end(),3); // 
	// 或者这样写, auto pos = find(v.begin(),v.end(),3);
	
	v.insert(pos,30); //有可能导致扩容,迭代器失效
	cout  << *pos << endl; //error, 访问野指针
}

erase导致迭代器失效

erase使迭代器失效的原理

迭代器指向一个元素后,vector调用erase后,迭代器指向的这个元素被覆盖了。所以此时的迭代器在编译器环境下被认为错误。因为数组vector中没有这个被覆盖的元素了,数组中没有想要的那个元素了,所以迭代器就已经失效了。
所以,erase失效主要是指这个位置的值已将改变了,含义已经改变了

vs下的stl是pj版本的,自己加了检查,所以下面的程序就会崩溃。

int main()
{
	vector<int> v = {1,2,3,4};
    vector<int>::iterator pos = find(v.begin(),v.end(),3);
   
	v.erase(pos);
	cout <<  *pos << endl;  //vs下会报错(pj版本加的检查), linux下不报错
    
}
 

总结: 迭代器pos指向的是3这个元素,erase调用之后3这个值就被覆盖掉了。含义已经改变了,所以vs下,禁止在访问这个迭代器pos了。

猜你喜欢

转载自blog.csdn.net/weixin_43939593/article/details/105920398