vector :: resize()和vector :: reserve()之间的选择
我预先分配一些内存给我的一个vector
成员变量。 下面的代码是最小的部分
class A { vector<string> t_Names; public: A () : t_Names(1000) {} };
现在在某个时间点,如果t_Names.size()
等于1000
。 我打算把尺寸增加100
。 那么如果达到1100
,再增加100
等等。
我的问题是, vector::resize()
和vector::reserve()
。 在这种情况下有没有更好的选择?
编辑 :我对t_Names
有一些精确的估计。 我估计大约700
到800
。 但在某些 (很少)的情况下,它可以增长超过1000
。
这两个功能做了很大的不同的事情!
resize()
方法(以及传递给构造函数的参数等价于此)将向vector中插入或删除适当数量的元素以使其具有给定的大小(它具有可选的第二个参数来指定它们的值)。 它会影响size()
,迭代将遍及所有这些元素,push_back将在它们之后插入,并且可以使用operator[]
直接访问它们。
reserve()
方法只分配内存,但保持未初始化。 它只影响capacity()
,但size()
将保持不变。 对象没有任何价值,因为没有任何东西被添加到向量中。 如果插入元素,则不会进行重新分配,因为这是事先完成的,但这是唯一的影响。
所以这取决于你想要的。 如果您需要1000个默认项目的数组,请使用resize()
。 如果你想要一个数组,你期望插入1000个项目,并希望避免一些分配,使用reserve()
。
编辑: Blastfurnace的评论让我再次阅读这个问题,并认识到,在你的情况下,正确的答案是不预先手动分配 。 只要继续插入元素在你需要的尽头。 该矢量将根据需要自动重新分配,并且比上述手动方式更有效。 reserve()
有意义的唯一情况是,当您对总大小进行合理的精确估计时,您需要提前轻松获得这些大小。
编辑2 :广告问题编辑:如果你有初步估计,然后reserve()
该估计。 如果结果不够,只要让矢量做这件事。
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
输出( 在线演示 ):
1 1 0 1
所以如果你不想要默认创建的对象, resize()
可能是不可取的。 这也将是缓慢的。 此外,如果你push_back()
新的元素,矢量的size()
将通过分配新的内存 (也意味着移动现有的元素到新分配的内存空间)进一步增加。 如果你在开始时使用了reserve()
来确保已经有足够的分配内存,那么当你使用push_back()
时候,vector的size()
会增加, 但是它不会再分配新的内存,直到它用完你为它保留的空间 。
保留时不希望对象被初始化。 另外,当您调整大小时,您可能更愿意在逻辑上区分并跟踪其计数与其使用次数。 因此界面中存在行为差异 – 保留时向量将表示相同数量的元素,在您的场景中调整大小时,向量将为100个元素。
在这种情况下有没有更好的选择?
在打击违约行为时,完全取决于你的目标。 有些人会喜欢自定义的分配器 – 但是我们真的需要更好地了解你在程序中试图解决什么问题,以便为你提供建议。
许多矢量实现只是在必须增长的时候将已分配的元素数加倍 – 你是否试图最大限度地减少峰值分配的大小,或者你是否为一些无锁定的程序或其他东西保留足够的空间?
根据你的描述,看起来你想“保留”向量t_Names的分配存储空间。
请注意, resize
初始化刚刚分配,但不建构的新分配的向量。 因此,“储备”比“调整” 要快得多,
您可以参考有关调整大小和保留区别的文档