vector内存分配特点
vector有一个特点:内存空间只会增长,不会减小。为了支持快速的随机访问,vector容器的元素以连续方式存放,每添加一个元素时,都需要保证连续存放的特性,若空间不足则需要重新分配空间、拷贝元素。因此在创建vector时,对其分配的内存空间比当前需要的要多一些,也就是说预留一些额外的存储空间用于存放新添加的元素。
vector有两个函数,一个是capacity()
,返回对象缓冲区(vector维护的内存空间)实际申请的空间大小,另一个size()
,返回当前对象缓冲区存储数据的个数。也就是说,前者是占用空间的大小,后者是其中存放数据的多少,并且capacity永远大于等于size。当两者相等时,vector就会重新分配内存,扩大capacity。
为什么要释放内存
实际上vector不需要手动释放,当超出范围或者程序结束时会自动回收,对于数据量较小的变量来说,不需要考虑内存释放的问题。但对于数据量很大,占用内存空间较多的变量,有时候需要考虑内存占用的问题。由于上面所说的性质,当某个变量已经不需要或者被clear的时候,capacity的值并没有变,所占的空间也没有变,这时就需要其他函数解决。
下面介绍两种方法。
内存释放示例
swap()函数
在《Effective STL》给出的解决方案是:1
2
3
4
5vector<type> v;
//.... 这里添加许多元素给v
//.... 这里删除v中的许多元素
vector<type>(v).swap(v);
//此时v的容量已经尽可能的符合其当前包含的元素数量
即先创建一个尽可能小的符合所需数据的临时拷贝,再将该拷贝与原先的vector进行交换,交换后临时变量会被销毁,内存释放。此时v就是临时拷贝,而交换后的临时拷贝是v的数据,只不过已经被销毁。下面是测试代码。
1 |
|
shrink_to_fit()函数
c++11中给出了一个新的解决方案。这个函数是专门为减小容器的容量设计的,在cplusplus中有如下定义:
Requests the container to reduce its capacity to fit its size.
The request is non-binding, and the container implementation is free to optimize otherwise and leave the vector with a capacity greater than its size.
shrink_to_fit()会在几种典型情况下放弃重分配,如元素类型不支持无异常移动、使用拷贝完成内存重分配期间某个元素构造抛出异常、重分配新位置需要的内存失败、capacity()和size()相等。此时函数回滚容器到调用前状态,错误不返回。
示例代码:
1 |
|
输出结果为:
- capacity of myvector: 100
- capacity of myvector: 100
- capacity of myvector: 10