vector的内存分配方式

关于STL容器,最神奇的事情之一是只要不超过它们的最大大小,它们就可以自动增长到足以容纳你放进去的数据。(要知道这个最大值,只要调用名叫max_size的成员函数。)对于vector和string,只要需要更多空间,就以realloc等价的思想来增长。这个类似于realloc的操作有四个部分:

  1. 分配新的内存块,它有容器目前容量的几倍。在大部分实现中,vector和string的容量每次以2为因数增长。也就是说,当容器必须扩展时,它们的容量每次翻倍。
  2. 把所有元素从容器的旧内存拷贝到它的新内存。
  3. 销毁旧内存中的对象。
  4. 回收旧内存。

vector内存增长(详见

vector所有的内存相关问题都可以归结于它的内存增长策略。vector有一个特点就是:内存空间只会增长不会减少。vector有两个函数,一个是capacity(),返回对象缓冲区(vector维护的内存空间)实际申请的空间大小,另一个size(),返回当前对象缓冲区存储数据的个数。对于vector来说,capacity是永远大于等于size的,档capacity和size相等时,vector就会扩容,capacity变大。

比如说vector最常用的push_back操作,它的整个过程是怎么一个机制呢?这个问题经常在面试中出现。

这个问题其实很简单,在调用push_back时,若当前容量已经不能够放入新的元素(capacity=size),那么vector会重新申请一块内存,把之前的内存里的元素拷贝到新的内存当中,然后把push_back的元素拷贝到新的内存中,最后要析构原有的vector并释放原有的内存。所以说这个过程的效率是极低的,为了避免频繁的分配内存,C++每次申请内存都会成倍的增长,例如之前是4,那么重新申请后就是8,以此类推。当然不一定是成倍增长,比如在我的编译器环境下实测是0.5倍增长,之前是4,重新申请后就是6。

内存释放

就像前面所说的,vector的内存空间是只增加不减少的,我们常用的操作clear()和erase(),实际上只是减少了size(),清除了数据,并不会减少capacity,所以内存空间没有减少。那么如何释放内存空间呢,正确的做法是swap()操作。

swap交换技巧实现内存释放思想:vector()使用vector的默认构造函数建立临时vector对象,再在该临时对象上调用swap成员,swap调用之后原来vector占用的空间就等于一个默认构造的对象的大小,临时对象就具有原来对象v的大小,而该临时对象随即就会被析构,从而其占用的空间也被释放。

 

std::vector<T>().swap(X)
作用相当于:
{
std::vector<T>  temp(X);
temp.swap(X);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值