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 展开
#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 展开
3个回答
展开全部
这个问题是这样的,应该是这样吧
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或者怎么样,应该就会差不少了),你只要明白为什么差距是因为这是两次空间申请,明白为什么,就行了。
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()就一致了⋯⋯大概⋯⋯你可以试试
展开全部
简单来说就是迭代器失效了,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);
很明显, 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);
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
对于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不好吗?
下面是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不好吗?
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询