std :: vector preallocation(size n,capacity n + 2)

时间:2015-04-15 15:21:14

标签: c++ vector std stdvector allocation

我的用例如下: 从二进制文件中读取大小为n的向量。

在其他变体(iostreams,在我的情况下自定义代码进行解压缩)中,我可以用这样的语义做一些事情:

vector<myElem> v;
v.resize(n); // from my understanding v now has size n and capacity n
fread(v.data(), sizeof(myElem), n, myFile);

然而,稍后我将不得不(重复地)向这样的向量添加和删除两个元素。 (虽然这听起来很愚蠢,但它可以产生积极的效果,可以将标记值添加到列表中,这样排序列表的交叉点就不必为绑定检查添加比较了。)

为此,我希望预先量化一个大小为n且容量为n + 2的向量。 我想我可以这样做:

vector<myElem> v;
v.resize(n + 2); // from my understanding v now has size n + 2 and capacity n + 2 
v.pop_back();
v.pop_back(); // v now has size n and most probably still has capacity 2 (unless n is pretty small)
fread(v.data(), sizeof(myElem), n, myFile);

显然,这既不美观,也不保证能像我所说的那样行事。在实践中,我认为它应该对大n采取这种方式,如果小n应该发生,重新分配并不重要。

但是,如果有更好的方法,那将会很棒。

编辑:

我不确定如何在我的案例中使用reserve。如果我保留n + 2的容量,则向量的大小仍为0。如果我调整为n,我也会更改容量。

如果我先调整大小然后调整,我会分配内存两次并在此过程中复制整个矢量。

3 个答案:

答案 0 :(得分:3)

您可以使用v.reserve(n + 2)更改vector的容量,而无需更改其大小。查看documentation以更好地了解正在发生的事情。

答案 1 :(得分:1)

您对容量的理解并不正确:

v.resize(n); // from my understanding v now has size n and capacity n

v的大小为n,是的,但您可以说的容量是>= n。它可以是n,可以是n + 1,也可以是3 * n。类似地:

v.resize(n + 2); // from my understanding v now has size n + 2 and capacity n + 2 
v.pop_back();
v.pop_back(); // v now has size n and most probably still has capacity 2 (unless n is pretty small)

此时,我们可以肯定地说v.size() == n && v.capacity() >= n + 2

如果你想做的是

  

我希望预先量化一个大小为n且容量为n + 2的载体

那简单地说:

v.reserve(n + 2); // capacity >= n+2, size == 0
v.resize(n);      // capacity >= n+2, size == n

答案 2 :(得分:0)

你想要

v.reserve(n+2);
v.resize(n);

保证为您提供大小为n且容量至少为n+2的向量:

  

23.3.7.3载体容量

     

void reserve(size_type n)

     

...在调用reserve()之后发生的插入过程中不会发生重新分配   直到插入会使向量的大小大于capacity()的值。

     

void resize(size_type n)

     

...如果size() < szsz - size()默认插入的元素添加到序列

因此调整大小大于当前大小相当于插入元素,并且在保留之后,没有插入操作可以重新分配内存,直到其大小超过保留容量...