C++ std::vector::resize() 与 std::vector::reserve()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13029299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
std::vector::resize() vs. std::vector::reserve()
提问by Mr.C64
There is a thread in the comments section in this postabout using std::vector::reserve()
vs. std::vector::resize()
.
这篇文章的评论部分有一个关于使用std::vector::reserve()
vs. 的主题std::vector::resize()
。
Here is the original code:
这是原始代码:
void MyClass::my_method()
{
my_member.reserve(n_dim);
for(int k = 0 ; k < n_dim ; k++ )
my_member[k] = k ;
}
I believe that to write elements in the vector
, the correct thing to do is to call std::vector::resize()
, not std::vector::reserve()
.
我相信要在中写元素vector
,正确的做法是调用std::vector::resize()
,而不是std::vector::reserve()
。
In fact, the following test code "crashes" in debug builds in VS2010 SP1:
事实上,以下测试代码在 VS2010 SP1 的调试版本中“崩溃”:
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.reserve(10);
v[5] = 2;
return 0;
}
Am I right, or am I wrong? And is VS2010 SP1 right, or is it wrong?
我是对的,还是我错了?VS2010 SP1 是对的,还是错的?
回答by CashCow
There are two different methods for a reason:
有两种不同的方法是有原因的:
std::vector::reserve
will allocate the memory but will not resize your vector, which will have a logical size the same as it was before.
std::vector::reserve
将分配内存但不会调整向量的大小,向量的逻辑大小与以前相同。
std::vector::resize
will actually modify the size of your vector and will fill any space with objects in their default state. If they are ints, they will all be zero.
std::vector::resize
将实际修改向量的大小,并将用处于默认状态的对象填充任何空间。如果它们是整数,它们都将为零。
After reserve, in your case, you will need a lot of push_backs to write to element 5. If you don't wish to do that then in your case you should use resize.
在保留之后,在您的情况下,您将需要大量 push_backs 来写入元素 5。如果您不想这样做,那么在您的情况下,您应该使用调整大小。
回答by lucasg
Answered here by Jan Hudec: Choice between vector::resize() and vector::reserve()
Jan Hudec在此回答:vector::resize() 和 vector::reserve() 之间的选择
The two functions do vastly different things.
The resize() method (and passing argument to constructor is equivalent to that) will insert given number of elements to the vector (it has optional second argument to specify their value). It will affect the size(), iteration will go over all those elements, push_back will insert after them and you can directly access them using the operator[].
The reserve() method only allocates memory, but leaves it uninitialized. It only affects capacity(), but size() will be unchanged. There is no value for the objects, because nothing is added to the vector. If you then insert the elements, no reallocation will happen, because it was done in advance, but that's the only effect.
So it depends on what you want. If you want an array of 1000 default items, use resize(). If you want an array to which you expect to insert 1000 items and want to avoid a couple of allocations, use reserve().
EDIT: Blastfurnace's comment made me read the question again and realize, that in your case the correct answer is dont't preallocate manually. Just keep inserting the elements at the end as you need. The vector will automatically reallocate as needed and will do it more efficiently than the manual way mentioned. The only case where reserve() makes sense is when you have reasonably precise estimate of the total size you'll need easily available in advance.
EDIT2: Ad question edit: If you have initial estimate, than reserve() that estimate and if it turns out to be not enough, just let the vector do it's thing.
这两个函数做的事情大不相同。
resize() 方法(并将参数传递给构造函数等效于该方法)将给定数量的元素插入向量(它具有可选的第二个参数来指定它们的值)。它会影响 size(),迭代将遍历所有这些元素,push_back 将在它们之后插入,您可以使用 operator[] 直接访问它们。
Reserve() 方法只分配内存,但未初始化。它只影响容量(),但大小()将保持不变。对象没有价值,因为没有向向量添加任何内容。如果然后插入元素,则不会发生重新分配,因为它是提前完成的,但这是唯一的效果。
所以这取决于你想要什么。如果您想要一个包含 1000 个默认项的数组,请使用 resize()。如果您想要一个数组,您希望在其中插入 1000 个项目并希望避免多次分配,请使用 Reserve()。
编辑:Blastfurnace 的评论让我再次阅读了这个问题并意识到,在你的情况下,正确的答案是不要手动预分配。只需根据需要在最后插入元素即可。矢量将根据需要自动重新分配,并且比提到的手动方式更有效。Reserve() 唯一有意义的情况是当您对需要的总大小进行合理精确的估计时,可以轻松获得。
EDIT2:广告问题编辑:如果你有初步估计,比reserve()估计,如果结果还不够,就让向量做它的事情。
回答by James Kanze
It depends on what you want to do. reserve
does notadd any
elements to the vector
; it only changes the capacity()
, which
guarantees that addingelements will not reallocate (and e.g.
invalidate iterators). resize
adds elements immediately. If you want
to add elements later (insert()
, push_back()
), use reserve
. If you
want to access elements later (using []
or at()
), use resize
. So
youre MyClass::my_method
can be either:
这取决于你想做什么。 reserve
也未添加到任何元件vector
; 它只更改capacity()
,从而保证添加元素不会重新分配(例如使迭代器无效)。 resize
立即添加元素。如果您想稍后添加元素 ( insert()
, push_back()
),请使用reserve
. 如果您想稍后访问元素(使用[]
或at()
),请使用resize
。所以你MyClass::my_method
可以是:
void MyClass::my_method()
{
my_member.clear();
my_member.reserve( n_dim );
for ( int k = 0; k < n_dim; ++ k ) {
my_member.push_back( k );
}
}
or
或者
void MyClass::my_method()
{
my_member.resize( n_dim );
for ( int k = 0; k < n_dim; ++ k ) {
my_member[k] = k;
}
}
Which one you chose is a question of taste, but the code you quote is clearly incorrect.
您选择哪个是品味问题,但您引用的代码显然是错误的。
回答by Konrad Rudolph
Yes you're correct, Luchian just made a typo and is probably too coffee-deprived to realise his mistake.
是的,你是对的,Luchian 只是打错了一个字,可能因为喝咖啡太少而无法意识到自己的错误。
回答by Dula
There probably should be a discussion about when both methods are called with a number that's LESS than the current size of the vector.
可能应该讨论一下何时使用小于向量当前大小的数字调用这两种方法。
Calling reserve()
with a number smaller than the capacity will not affect the size or the capacity.
拨打reserve()
小于容量的号码不会影响大小或容量。
Calling resize()
with a number smaller than current size the container will be reduced to that size effectively destroying the excess elements.
resize()
使用小于当前大小的数字调用容器将减小到该大小,从而有效地破坏多余的元素。
To sum up resize()
will free up memory whereas reserve()
will not.
总而言之resize()
会释放内存,而reserve()
不会。
回答by odinthenerd
resize actually changes the amount of elements in the vector, new items are default constructed if the resize causes the vector to grow.
调整大小实际上会改变向量中元素的数量,如果调整大小导致向量增长,则默认构造新项目。
vector<int> v;
v.resize(10);
auto size = v.size();
in this case size is 10.
在这种情况下,大小为 10。
reserve on the other hand only requests that the internal buffer be grown to the specified size but does not change the "size" of the array, only its buffer size is changed.
另一方面,reserve 仅请求将内部缓冲区增长到指定的大小,但不更改数组的“大小”,仅更改其缓冲区大小。
vector<int> v;
v.reserve(10);
auto size = v.size();
in this case size is still 0.
在这种情况下,大小仍然是 0。
So to answer your question, yes you are right, even if you reserve enough space you are still accessing uninitialized memory with the index operator. With an int thats not so bad but in the case of a vector of classes you would be accessing objects which have not been constructed.
因此,要回答您的问题,是的,您是对的,即使您保留了足够的空间,您仍在使用索引运算符访问未初始化的内存。使用 int 还不错,但在类向量的情况下,您将访问尚未构造的对象。
Bounds checking of compilers set to debug mode can obviously be confused by this behavior which may be why you are experiencing the crash.
设置为调试模式的编译器的边界检查显然会被这种行为混淆,这可能是您遇到崩溃的原因。