1、vector 内存增长模式
vector是一种特殊的数组,因此其内存必然是连续的。它的连续是建立在不断地对内存的预分配上的,即不断地销毁当前,重新建立内存,效率有点低。
vector 容器扩容的过程需要经历以下 3 步:(当 size == capacity 时候,如果要添加元素,就会扩充)
- 完全弃用现有的内存空间,重新申请更大的内存空间;
- 将旧内存空间中的数据,按原有顺序移动到新的内存空间中;
- 最后将旧的内存空间释放。
这也就解释了,为什么 vector 容器在进行扩容后,与其相关的指针、引用以及迭代器可能会失效的原因。
由此可见,vector 扩容是非常耗时的。为了降低再次分配内存空间时的成本,每次扩容时 vector 都会申请比用户需求量更多的内存空间(这也就是 vector 容量的由来,即 capacity>=size),以便后期使用。 vector 容器扩容时,不同的编译器申请更多内存空间的量是不同的。以 VS 为例,它会扩容现有容器容量的 50%。
关于容量和内存,存在几个函数,size capacity max_size resize reserve
1)、size
size() 函数返回的是 vector 实际有的元素个数。
2)、capacity
capacity() 函数返回的是 vector 总空间的大小,包括已经使用 和 未使用的。
3)、max_size
max_size() 返回容器最大的可以存储元素数量。这是系统或者库所实施的限制。但是容器不一定保证能达到该大小,有可能在还未达到该大小的时候,就已经无法继续分配任何的空间了。
4)、resize
void resize (size_type n);
void resize (size_type n, const value_type& val);
如果n 小于当前容器的size, 则保留从first 到 n的元素,后面的删除并销毁。
如果n 大于当前容器的size,则通过在末尾插入所需数量的元素来扩展内容,以达到n的大小。如果指定了val,则将新元素初始化为val的副本,否则,将对它们进行值初始化。
如果n 也大于当前容器的 capacity,则将自动重新分配已分配的存储空间。
5)、reserve
可以调用 reserve() 成员函数来增加容器的容量(但并不会改变存储元素的个数)即 capacity会变化 为 reserve指定的值,但是 size 是不变的。
#include<vector>
#include<iostream>
using namespace std;
int main()
{
//定义一个 vector, capacity size 都为0;
vector<int> vec;
cout << "vec capacity: " << vec.capacity() << endl;
cout << "vec size: " << vec.size() << endl;
//初始化一个vector, 不是动态添加,因此刚开始capacity size相等
vector<int> vec1{ 1,2,3,4 };
vec = vec1;
cout << "vec capacity: " << vec.capacity() << endl;
cout << "vec size: " << vec.size() << endl;
//动态添加,vs里,capacity 增加原有的50%,即从4 增加到6,size是实际大小。
vec.push_back(1);
cout << "vec capacity: " << vec.capacity() << endl;
cout << "vec size: " << vec.size() << endl;
// reserve 改变的是 capacity,不改变size
vec.reserve(10);
cout << "vec capacity: " << vec.capacity() << endl;
cout << "vec size: " << vec.size() << endl;
// resize 改变的是size,并且有可能改变capacity,具体看上文 4)
vec.resize(3);
cout << "vec capacity: " << vec.capacity() << endl;
cout << "vec size: " << vec.size() << endl;
vec.resize(13);
cout << "vec capacity: " << vec.capacity() << endl;
cout << "vec size: " << vec.size() << endl;
return 0;
}