vector对象是如何增长的
为了支持快速随机访问,vector元素类似数组一样是连续存储的。但是与数组不同,vector或string的容器大小是可变的。因此,vector和string当没有空间容纳新元素时,将已有元素从旧位置移动到新空间中(通过右值引用实现),然后添加新元素,释放旧存储空间。但如果我们每添加一个新元素就执行一次这样的内存分配和释放,性能会很慢,因此,当不得不获取新的内存空间时,vector和string的实现通常会分配比新的空间需求更大的内存空间。
1.管理容器的成员函数
vector和string有一些成员函数,允许管理内存分配。如下表:
shrink_to_fit只适用于vector、string和deque
capacity和reserve只适用于vector和string
c.shrink_to_fit() 请求将capacity()减少为与size()相同大小,编译器可忽 略此请求。
c.capacity() 返回c的容量,即不重新分配空间最多可以保存多少元素
c.reserve(n) 分配至少能容纳n个元素的内存空间
c.resize(n) 调整c的大小为n个元素,若n<c.size(),多余的元素被丢 弃,若必须添加新的元素,对新元素值初始化。
c.resize(n,t) 调整c的大小为n个元素。任何新添加的元素初始化为t
reserve并不改变容器中的元素,仅影响vector预先分配多大的内存空间
resize只改变元素的数目,而不是容器的容量,不能用resize来减少容器预留空间
只有当需要的内存空间超过当前容量时,reserve调用才会改变vector的容量,如果需求大小大于当前容量,reserve至少分配与需求一样大的内存空间;如果需求小于等于当前容量,reserve什么都不做。因此,调用reserve之后,capacity将会大于等于传递给reserve的参数。如:
vector<int> v{1, 2, 3, 4};
cout << v.capacity() << endl; //值为4
v.reserve(3); //需要内存空间小于当前空间,reserve什么也不做
cout << v.capacity() << endl; //值为4
v.reserve(10); //需要的内存空间大于当前空间,将扩容
cout << v.capacity() << endl; //值为10
2.capacity和size
①capacty和size的区别:
- size是指它已经保存的元素的数目。
- capacity是指在不分配新的内存空间的前提下它最多保存多少元素。
如:
vector<int> v; //size为0,capacity为0
cout << "size:" << v.size() << " capacity:" << v.capacity() << endl;
for (int i = 0; i < 24; ++i) {
v.push_back(i);
}
//size为24,capacity应该大于24
cout << "size:" << v.size() << " capacity:" << v.capacity() << endl;
//输出结果为:
//size:0 capacity:0
//size:24 capacity:28
一个空的vector的size为0,它的capacity也为0。 添加元素时,当需求超过当前容量capacity的值时会重新分配内存,具体分配多少额外内存空间视情况而定。
②vector和string的内存空间分配策略:
只有在执行插入操作时size和capacity相等,或者调用resize或reserve时给定的大小超过当前capacity,vector才可能重新分配空间内存。分配多少额外空间,取决于具体实现。虽然不同实现可以采用不同的分配策略,但是所有重新分配的策略都会采用push_back向vector添加元素提高效率。 如:
vector<int> v;
int i = 0;
for (; i < 5; ++i) {
v.push_back(i);
}
cout << "size:" << v.size() << " capacity:" << v.capacity() << endl;
for (; i < v.capacity(); ++i) {
v.push_back(i);
}
cout << "size:" << v.size() << " capacity:" << v.capacity() << endl;
v.push_back(10);
cout << "size:" << v.size() << " capacity:" << v.capacity() << endl;
结果为:
可以看出,当需要的空间超过当前的capacity才会重新分配空间。