您的位置:首页 > 其它

使用reserve要再次避免不必要的分配

2015-08-14 19:45 281 查看


关于STL容器,最了不起的一点是,它们会自己主动增长以便容纳下你放入当中的数据,仅仅要没有超出它们的最大限制就能够。对于vector和string,增长过程是这样来实现的:每当须要很多其它空间时,就调用与realloc类似的操作。

这一类似于realloc的操作分为4部分:

分配一块大小为当前容量的某个倍数的新内存。

在大多数实现中,vector和string的容量每次以2的倍数增长,即,每当容器须要扩张时,它们的容量即加倍。

把容器的全部元素从旧的内存复制到新的内存中。

析构掉旧内存中的对象。

释放旧内存。

reserve成员函数能使你把又一次分配的次数降低到最低限度,从而避免了又一次分配内存和指针/迭代器/引用失效带来的开销。在解释reserve如何做到这一点之前。我将简单概括一下4个相互关联,但有时会被混淆的成员函数。在标准容器中,仅仅有vector和string提供了全部这4个函数:

size()说明了改容器中有多少个元素。它不会告诉你该容器为自己所包括的元素分配了多少内存。

capacity()说明了改容器利用已经分配的内存能够容纳多少个元素。

这是容器所能容纳的元素总数。而不是它还能容纳多少个元素。

假设你想知道一个vector由多少为被使用的内存,你就得从capacity()中减去size()。假设size和capacity返回相同的值。就说明容器中不再有剩余空间了。

resize(Container::size_type n)强迫容器改变到包括n个元素的状态。

在调用resize之后,size将返回n。

假设n比当前的大小要小,则容器尾部的元素将会被析构掉。假设n比当前的大小要大。则通过默认构造函数创建的新元素将被加入到容器的末尾。假设n比当前的容量要大,那么在加入元素之前,将先又一次分配内存。

reserve(Container::size_type n)强迫容器把它的容量变为至少是n。前提是n不小于当前的大小。这一般会导致又一次分配,由于容量会添加。(假设n比当前的容量小,则vector忽略该调用。什么也不做;而string则可能把自己的容量减为size()和n中的最大值,可是string的大小肯定保持不变。)

比如:假定想创建一个包括1到1000之间的值的vector<int>。

假设不使用reserve。你可能会这样做:

vector<int> v;

for (int i = 1;i <= 1000;++i)

v.push_back(i);

该循环在进行过程中将导致2到10次又一次分配。假设使用reserve,例如以下所看到的:

vector<int> v;

v.reserve(1000);

for (int i = 1;i <= 1000;++i)

v.push_back(i);

则在循环过程中将不会再发生又一次分配。

假设想除去多余的容量。请參阅怎样有效除去多余的容量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: