C++ 在vector::resize()和vector::reserve()之间进行选择

C++ 在vector::resize()和vector::reserve()之间进行选择,c++,vector,C++,Vector,我正在为a向量成员变量预先分配一些内存。下面的代码是最小的部分 class A { vector<string> t_Names; public: A () : t_Names(1000) {} }; A类{ 向量t_名称; 公众: A():t_名称(1000){} }; 现在在某个时间点,如果t\u Names.size()等于1000。我打算把尺寸增加100。然后,如果达到1100,则再次增加100,依此类推 我的问题是,在vector::resize()和vecto

我正在为a
向量
成员变量预先分配一些内存。下面的代码是最小的部分

class A {
  vector<string> t_Names;
public:
  A () : t_Names(1000) {}
};
A类{
向量t_名称;
公众:
A():t_名称(1000){}
};
现在在某个时间点,如果
t\u Names.size()
等于
1000
。我打算把尺寸增加100。然后,如果达到
1100
,则再次增加
100
,依此类推

我的问题是,在
vector::resize()
vector::reserve()
之间选择什么。在这种情况下有更好的选择吗

编辑:我对
t\u名称
有某种精确的估计。我估计大约在
700
800
之间。但是,在某些(很少)情况下,它的增长可能超过
1000

resize()
不仅分配内存,而且还创建所需大小的实例,作为参数传递给
resize()
。但是
reserve()
只分配内存,不创建实例。就是

std::vector<int> v1;
v1.resize(1000); //allocation + instance creation
cout <<(v1.size() == 1000)<< endl;   //prints 1
cout <<(v1.capacity()==1000)<< endl; //prints 1

std::vector<int> v2;
v2.reserve(1000); //only allocation
cout <<(v2.size() == 1000)<< endl;   //prints 0
cout <<(v2.capacity()==1000)<< endl; //prints 1

因此,如果您不希望使用默认创建的对象,则可能不希望使用
resize()。它也会很慢。此外,如果
push_back()
new elements to it,向量的
size()
将通过分配新内存(这也意味着将现有元素移动到新分配的内存空间)进一步增加。如果您在开始时使用了
reserve()
,以确保已分配足够的内存,则当您
向后推()
时,向量的
大小()
将增加,但它不会再次分配新内存,除非它用完了您为它保留的空间

这两个函数的作用截然不同

该方法(将参数传递给构造函数与之等效)将向向量插入或删除适当数量的元素,使其具有给定的大小(它有可选的第二个参数来指定其值)。它将影响
大小()
,迭代将遍历所有这些元素,推回将在它们之后插入,您可以使用
操作符[]
直接访问它们

该方法仅分配内存,但未对其进行初始化。它只影响
capacity()
,但
size()
将保持不变。对象没有值,因为没有向向量添加任何内容。如果随后插入元素,则不会发生重新分配,因为这是提前完成的,但这是唯一的效果

所以这取决于你想要什么。如果需要1000个默认项的数组,请使用
resize()
。如果希望数组中插入1000个项目,并且希望避免几次分配,请使用
reserve()

编辑:高炉的评论让我再次阅读了问题,并意识到,在您的情况下,正确答案是不要手动预分配。只需根据需要在末尾插入元素即可。矢量将根据需要自动重新分配,并且比上述手动方式更有效。
reserve()
唯一有意义的情况是,您对所需的总大小有了合理准确的估计,并且可以提前轻松获得


EDIT2:广告问题编辑:如果您有初始估计,那么
reserve()
该估计。如果结果还不够,就让向量做它该做的事情。

根据您的描述,看起来您希望“保留”分配的向量t_名称的存储空间

注意,
resize
初始化新分配的向量,其中
reserve
仅分配而不构造。因此,“保留”比“调整大小”快得多


如果不希望在保留时初始化对象,则可以参考有关和

保留差异的文档。此外,在调整大小时,您可能更愿意在逻辑上区分和跟踪其计数与使用计数。因此,接口中存在行为差异-向量在保留时表示相同数量的元素,在场景中调整大小时将大100个元素

在这种情况下有更好的选择吗

这完全取决于你在对抗默认行为时的目标。有些人会喜欢定制的分配器——但我们确实需要更好地了解您试图在程序中解决的问题,以便更好地为您提供建议


fwiw,许多向量实现在必须增长时只会将分配的元素数增加一倍-您是在尝试最小化峰值分配大小,还是在尝试为一些无锁程序或其他东西保留足够的空间?

您意识到这样做意味着向量增长不再是固定时间的摊销,您将失去其中一个使用
std::vector
的性能优势相关,请参见Dobbs博士的网站。请改为参考此处:和()感谢添加链接,seheI已编辑了该问题。我确实对
向量有一定的估计值
@Jan:好吧,它是否脆弱取决于您维护所需属性的难度。类似于
x.reserve(x.size()+newdata);向量::迭代器特殊元素=获取特殊元素(x);对于(int i=0;i
在保留空间方面非常健壮。我不知道实际会添加多少元素,但我有一个上限。当然,当有疑问时,对于向量,你可以只使用索引而不是迭代器,差别通常可以忽略不计。你的措辞对已经知道正确答案的人来说是有意义的,但很容易误导需要提问的人。“resize()…将插入给定的num
1
1
0
1