C++ STL vector 迭代器 求助

#include<cstdio>#include<vector>#include<iterator>#include<algorithm>usingnamespacest... #include <cstdio>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
FILE *fpout;

int main()
{
fpout=fopen("test.out","w");
vector<int> a;
vector<int>::iterator pos;
a.clear();
a.push_back(1);
pos=a.begin();
fprintf(fpout,"%d\n",*pos);
a.push_back(2);
fprintf(fpout,"%d\n",*pos);
fprintf(fpout,"%d\n",&pos);
fprintf(fpout,"%d\n",&(a.begin()));
fclose(fpout);
return 0;
}
输出的两个数字分别是1 0(输出0应该是访问了未定义的地方)
输出的地址相差16.

这是为什么呢?我的pos一直指向那个元素1的地址,push_back的机制是怎样的呢?求解释。。悬赏++ing
展开
 我来答
longinus_dean
2012-02-19 · TA获得超过2282个赞
知道小有建树答主
回答量:1097
采纳率:50%
帮助的人:1523万
展开全部
这个问题是这样的,应该是这样吧

vector是什么呢,是一个可以随机访问的顺序表,你可以想象为就是一个稍稍高级点的数组吧

push_back的作用是向数组的末尾插入一个值

不过你要注意啊,数组和链表是有很大区别的,链表是不能随机访问的,第一个元素和第二个元素可能相距很远,这个明白吧?数组是可以顺序的随机访问的,第一个值的下一个地址就是第二个值,这个明白吧?

你首先push_back了一个1,vector是很笨的,它这时候可能就申请了一个空间,也就是相当于内部用new动态分配了一个int的空间,这个空间的起始地址就是你的变量pos

然后你又push_back了一个2,这样vector就放不下了啊,因为刚刚只申请了一个空间,所以这个时候要再申请至少两个空间,然后先把之前pos位置的老的值赋值到新空间里面,然后再在新空间里面push_back你的2。

因为这里出现了两次空间申请,两次new出来的地址当然不可能是一样的了,所以也就导致了最后pos和begin差距一定的数值⋯⋯这个16这个数字也有可能是其他数字啦,因为动态new出来的空间不一定就很有准(虽然说你每次运行你这个程序可能都得到16,但是你要是在两次push_back之间再new或者怎么样,应该就会差不少了),你只要明白为什么差距是因为这是两次空间申请,明白为什么,就行了。
追问
那这样怎么办呢?使用resize么
追答
resize会填充元素的,你可以reserve

例如你的代码是这样吧

vector a;
vector::iterator pos;
a.clear();
a.push_back(1);

你改成这样

vector a;
a.reserve(10);
vector::iterator pos;
a.clear();
a.push_back(1);

应该pos和a.begin()就一致了⋯⋯大概⋯⋯你可以试试
烽风锋
2012-02-20 · TA获得超过490个赞
知道小有建树答主
回答量:161
采纳率:50%
帮助的人:126万
展开全部
简单来说就是迭代器失效了,vector是动态数组,添加元素时,如果原来预留的空间不够,就会重新分配内存,然后把原来的元素拷贝构造过去,而一旦重新分配内存,原来的迭代器就会失效。
很明显, a.push_back(2);之后,内存重新分配了,原来的迭代器失效了。
解决方法,重新获取迭代器,你要牢记,对于vector而言,任何添加元素的动作,都有可能导致内存重新分配,原来的迭代器都要重新获取才能保持正确性。
进行一下修改就可以了:
pos=a.begin();
fprintf(fpout,"%d\n",*pos);
a.push_back(2);
pos=a.begin();
fprintf(fpout,"%d\n",*pos);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
wqzhishou
2012-02-22 · TA获得超过190个赞
知道小有建树答主
回答量:111
采纳率:0%
帮助的人:102万
展开全部
对于vector,有一个简单的规则,就是,push_back()后就不要再引用原来的迭代器,因为,它可能已经失效了。
下面是vector的大致实现。
template<class Ty> class Vector {
public:
Vector() : size_(0), space_(0), elem_(0) { }
//ATTENTION : don't forget explicit
explicit Vector(int size)
: size_(size), space_(size), elem_(new Ty[size]) { }
Vector(const Vector& v);
~Vector() { delete[] elem_; }

Vector& operator=(const Vector& v);

void resize(int newsize); //set new size
void reserve(int newalloc); //reserve space
int capacity() const { return space_; } //return space
//not check
Ty& operator[](int index) { return elem_[index]; }
//overload for const object
const Ty& operator[](int index) const { return elem_[index]; }

int size() const { return size_; }
void push_back(const Ty& d); //add a new element
private:
int size_;
int space_;
Ty* elem_;
};
template<calss Ty> void Vector<Ty>::resize(int newsize)
//make the vector have newsize elements
//initialize each new element with the default value
{
reserve(newsize);
for (int i=size_; i<newsize; ++i) elem_[i] = T();
size_ = newsize;
}
template<class Ty> void Vector<Ty>::reserve(int newalloc)
{
if (space_<=newalloc) return;

Ty* newptr = new Ty[newalloc];
for (int t=0; t<size_; ++t) newptr[t] = elem_[t];
delete[] elem_;
elem_ = newptr;
space_ = newalloc;
}
template<class Ty> void Vector<Ty>::push_back(const Ty& d)
//increase vector size by one and initialize the new element with d
{
//first determinate the space
if (space_==0) reserve(10);
else if (size_==space_) reserve(size_*2);

//second initialize the elements
elem_[size_] = d;
++size_;
}
还有,我实在不明白,为什么你会把fprintf和vector一起用,用fstream不好吗?
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式