vector的空间可扩充,支持随机存取访问,是一段连续线性的空间。所以它是动态空间,与之对比的array是静态的空间,不可扩充。简单来说,vector是数组的增强版。
Vector:动态空间,自扩充。吃多少用多少。因为支持随机存取,所以提供Random Access Iterators。普通指针可以作为vector的迭代器。vector<int>::iterator iter,则iter类型为int *
Vector数据结构:
迭代器start和finish执行已经被使用的范围,end_of_storage表示可用空间的尾部
容量:用于扩充,>=vector的大小
动态增加大小的原理:
取原大小两倍空间,拷贝原容器内容至新空间,成功了释放原空间,失败了仍然用原空间。
Inset(position,n,x):函数思路:
1)若备用空间>=新增元素个数,(1)若插入点后现有元素个数>新增元素个数,则将插入点后的所有元素放到储备空间的最后面,然后在插入点后插入新增元素;(2)若插入点后现有元素个数<=新增元素个数,则先在储备空间中复制若干元素,然后将插入点后的老元素复制到储备空间的后面,腾出的地方插入新元素
2)若备用空间<新增元素个数,分配额外内存为原内存两倍。将旧vector插入点之前元素复制到新空间,将新增元素复制到新空间,将旧v ector插入点之后元素复制到新空间
vector的容量十分重要,是因为:
1、一旦内存重新配置,与之相关的所有的reference、pointers、iterators都会失效。
2、内存配置很费时。
解决这个问题的方法有:
1、可以使用reserve()保留适当容量,减少重新配置内存的次数。示例代码:
- vector<string> sentence(1);
- sentence.reserve(50);
- vector<T> v(5);
注意:reserve不能缩减vector的容量。由此,我们可以知道,即使删除元素,其reference、pointers、iterators也会继续有效,指向动作发生前的位置。
但是插入操作可能使reference、pointers、iterators失效(因为可能会导致重新配置空间)。
使用swap函数可以缩减vector容量。因为两个vector交换内容后,他们的容量也会互换。
1、
- template<class T>
- void shrinkCapacity(vector<T> &v)
- {
- vector<T> tmp(v);
- v.swap(tmp);
- }
- vector<T>(v).swap(v);
都是先构造出一个临时vector对象,以v的元素进行初始化,再与v进行交换。需要注意的是:临时对象一般都是精确分配实际所需的内存。所以能够起到减小vector容量的效果。
迭代器失效的两种情况是:
1、在一个较小的位置上删除或者是移动元素。
2、由于容量的变换引起内存重新分配。
插入和移除元素,都会使“作用点”之后的各元素的reference、pointers、iterators失效。插入操作还可能引发内存重新分配,那么该容器上的所有的reference、pointers、iterators都会失效。
现在的C++标准保证vector的元素必须分布于连续空间中。对于vector中的一个合法索引,满足下列表达式:
&v[i] = &v[0] + i;
我们必须保证vector能够容纳所有数据。如果使用的是C-String,记住最后有个'\0'。
只要我们需要一个元素型别为T的数组,就可以采用vector<T>,然后传递第一个元素的地址给它。
注意:千万不要把迭代器当做第一元素的地址来传递。因为vector迭代器是由实作版本定义的,不一定是一个一般指针。
- printf("%s",v.begin());//ERROR(might work,but not portable)
- printf("%s",&v[0]);//OK