c++关于顺序容器指针迭代器失效问题

             当vector或者是string容器被重新分配的时候,则原来指向容器元素的指针、引用或者是迭代器失效。

            

             但是如果存储空间未重新分配,即当容器vec中有vec.capacity()>vec.size()时候,指向插入位置之前的元素的迭代器、指针和引用仍然有用,但是指向插入位置之后的任何位置的迭代器、指针和引用都会失效。

           下面将用程序分析:

          

#include<vector>
#include<iostream>
using namespace std;
int main()
{
	vector<int> sb(3);
		cout<<"capacity="<<sb.capacity()<<endl<<endl;
	sb.reserve(5);
	int ssd=0;
	for(vector<int>::iterator it=sb.begin();it!=sb.end();++it)
	    *it=ssd++;
	vector<int>::iterator iter=sb.begin(),mid=sb.begin()+sb.size()/2;
	cout<<"capacity="<<sb.capacity()<<endl<<endl;
	int k=11;
	while(iter!=mid)
	{
			if(*iter!=-7)
			//iter=sb.begin();
		//	sb.insert(iter,16);
          sb.insert(iter,k);
				for(vector<int>::iterator it=sb.begin();it!=sb.end();++it)
	           cout<<*it<<"\t";
	           cout<<endl;
	           k++;
		//	cout<<"\nmid="<<*mid<<"\titer="<<*iter<<endl;
	}
	
	return 0;
} 
程序运行结果:

技术分享

程序在编译的时候是没有错误的,但是在运行一段之后就开始报错。

首先对原来capacity为3的vector,用

reserve();

   函数将其capacity改为5.。

然后再vector头插入元素,当capacity()小于5时候都不会报错,这个很容易理解。

而是在我们插入第七个元素的时候报错,是因为我们在capacity为5时候其迭代器iter还是可用的,所以插入第六个元素还是正确。之后由于元素值大于了capacity所以要重新分配,使得迭代器失效。程序报错。



下面我们看看后面的插入元素的之后的迭代器是怎么失效的

#include<vector>
#include<iostream>
using namespace std;
int main()
{
	vector<int> sb(3);
		cout<<"capacity="<<sb.capacity()<<endl<<endl;
	sb.reserve(5);
	int ssd=0;
	for(vector<int>::iterator it=sb.begin();it!=sb.end();++it)
	    *it=ssd++;
	vector<int>::iterator iter=sb.begin(),mid=sb.begin()+sb.size()/2,iter_end=sb.end()-1;
	
	           
	cout<<"capacity="<<sb.capacity()<<endl<<endl;
	for(vector<int>::iterator it=sb.begin();it!=sb.end();++it)
	           cout<<*it<<"\t";
	           cout<<"\nend="<<*iter_end<<endl;
	int k=11;
	while(iter!=mid)
	{
			if(*iter!=-7)
			//iter=sb.begin();
		//	sb.insert(iter,16);
          sb.insert(iter,k);
				for(vector<int>::iterator it=sb.begin();it!=sb.end();++it)
	           cout<<*it<<"\t";
	           cout<<endl;
	           k++;
	           
	           
	           cout<<"end="<<*iter_end<<endl;
	           
	           
	           
		//	cout<<"\nmid="<<*mid<<"\titer="<<*iter<<endl;
	}
	
	return 0;
} 

修改程序之后我们加入语句

cout<<"end="<<*iter_end<<endl;
用来输出最后一个元素。

程序运行结果

技术分享

我们可以看到原来的最后一个元素应该是2.

在没有插入元素时候是正确的。

但在插入元素之后iter_end指的位置还是离初始位置三个元素的距离而不是最后的元素。

当最后一次重新分配的内存之后,原来迭代器所指的位置被释放了之后,得到的数值就是一个乱码值。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。