STL
vector和array的区别在于,数组为静态空间,一旦配置了就不能改变;如果需要一个更大或者更小的空间,需要重新设置数组的大小,这样才能重新配置新空间,并将元素从旧地址搬到新地址,再释放新的空间给系统。而vector是动态空间,随着新元素的加入,内部机制会自动扩充空间容纳新元素。
vector维护的是一块连续的线性空间。数据结构比较简单,通过两个迭代器start和finish分别指向配置的空间中目前被使用的头和尾,迭代器end_of_storage指向整块空间的尾。
template<class T,class Alloc=alloc>
class vector{
protected:
typedef simple_alloc<value_type,Alloc> data_allocator;
iterator start;
iterator finish;
iterator end_of_storge;
...
}
vector提供了许多构造函数,通常采用
vector(size_type n,const T& value){fill_initialize(n,value);}
来为vector赋大小和初值。
此时通过fill_initialize函数配置了n个空间,然后填充初值。
以下结合push_back来查看vector内存空间的变化:
int main(){
vector<string> ex(10,"34");
vector<string>::iterator iter;
for(iter=ex.begin();iter!=ex.end();iter++)
cout<<*iter;
cout<<"size"<<ex.size()<<"\ncapacity"<<ex.capacity();
ex.push_back("1");
cout<<"size"<<ex.size()<<"\ncapacity"<<ex.capacity();
ex.push_back("3");
cout<<"size"<<ex.size()<<"\ncapacity"<<ex.capacity();
ex.pop_back();
cout<<"size"<<ex.size()<<"\ncapacity"<<ex.capacity();
ex.clear();
cout<<"size"<<ex.size()<<"\ncapacity"<<ex.capacity();
}
如图可见,首先构造了大小为10的vectror,此时配置了10个空间的大小,然后为每个空间配置了初值。当使用push_back向vector尾端添加新元素时,此时原空间不够用了。则以原先两倍的大小配置一块新空间,然后将原先的内容拷贝过来,之后在原内容尾端添加新的元素,释放原始空间。当我们对这部分空间的值clear之后,发现容量的大小仍然为之前扩容后的20个。
除此之外,当从原空间将元素拷贝到新空间之后,引起空间的重新配置,此时指向原先vector的迭代器就全部失效了。
int main()
{
vector<int> ex(10,9);
vector<int>::iterator iter1=ex.begin();
cout<<*iter1<<"\n";
ex.push_back(1);
cout<<*iter1<<"\n";
vector<int>::iterator iter2=ex.begin();
cout<<*iter2<<"\n";
}
如图可见,当构造vector之后,大小容量均为10,当push_back新的元素时,空间重新配置了,此时先前的迭代器仍然指向原来的地址空间。