std::vector 预分配(大小 n,容量 n + 2)

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

我的用例如下: 从二进制文件中读取的大小为 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,我也会更改容量。

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

您可以使用 v.reserve(n + 2) 来更改 vector 的容量而不改变其大小。查看 documentation 以更好地了解发生了什么。

您对容量的理解不正确:

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

如果你想做的是

I would love to prealloacte a vector with size n and capacity n + 2

那就简单了:

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

你想要

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

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

的矢量

23.3.7.3 vector capacity

void reserve(size_type n)

...No reallocation shall take place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the value of capacity().

void resize(size_type n)

...If size() < sz appaends sz - size() default-inserted elements to the sequence

所以调整到大于当前大小相当于插入元素,保留后,任何插入操作都不能重新分配内存,直到其大小超过保留容量...