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
所以调整到大于当前大小相当于插入元素,保留后,任何插入操作都不能重新分配内存,直到其大小超过保留容量...
我的用例如下:
从二进制文件中读取的大小为 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
appaendssz - size()
default-inserted elements to the sequence
所以调整到大于当前大小相当于插入元素,保留后,任何插入操作都不能重新分配内存,直到其大小超过保留容量...