size()函数返回的是已用空间大小,capacity()返回的是总空间大小,capacity()-size()则是剩余的可用空间大小。当size()和capacity()相等,说明vector目前的空间已被用完,如果再添加新元素,则会引起vector空间的动态增长。
由于动态增长会引起重新分配内存空间、拷贝原空间、释放原空间,这些过程会降低程序效率。因此,可以使用reserve(n)预先分配一块较大的指定大小的内存空间,这样当指定大小的内存空间未使用完时,是不会重新分配内存空间的,这样便提升了效率。只有当n>capacity()时,调用reserve(n)才会改变vector容量。
resize()成员函数改变元素的数目,至于空间的的变化需要看具体情况去分析,如下:
void resize(size_type __new_size, const _Tp& __x) {
if (__new_size < size())
erase(begin() + __new_size, end());
else
insert(end(), __new_size - size(), __x);
}
1、空的vector对象,size()和capacity()都为0
2、当空间大小不足时,新分配的空间大小为原空间大小的2倍。
3、使用reserve()预先分配一块内存后,在空间未满的情况下,不会引起重新分配,从而提升了效率。
4、当reserve()分配的空间比原空间小时,是不会引起重新分配的。
5、resize()函数只改变容器的元素数目,未改变容器大小。
6、用reserve(size_type)只是扩大capacity值,这些内存空间可能还是“野”的,如果此时使用“[ ]”来访问,则可能会越界。而resize(size_type new_size)会真正使容器具有new_size个对象。
不同的编译器,vector有不同的扩容大小。在vs下是1.5倍,在GCC下是2倍;
空间和时间的权衡。简单来说, 空间分配的多,平摊时间复杂度低,但浪费空间也多。
使用k=2增长因子的问题在于,每次扩展的新尺寸必然刚好大于之前分配的总和,也就是说,之前分配的内存空间不可能被使用。这样对内存不友好,最好把增长因子设为(1, 2),也就是1-2之间的某个数值。
对比可以发现采用成倍方式扩容,可以保证常数的时间复杂度,而增加指定大小的容量只能达到O(n)的时间复杂度,因此,使用成倍的方式扩容。