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有一些精确的估计。 我估计大约700800 。 但在某些 (很少)的情况下,它可以增长超过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初始化刚刚分配,但不建构的新分配的向量。 因此,“储备”比“调整” 要快得多,

您可以参考有关调整大小和保留区别的文档

Interesting Posts