vector :: resize()和vector :: reserve()之间的选择

iam*_*ind 142 c++ vector

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

class A {
  vector<string> t_Names;
public:
  A () : t_Names(1000) {}
};
Run Code Online (Sandbox Code Playgroud)

现在在某个时间点,如果t_Names.size()等于1000.我打算增加规模100.然后如果它到达1100,再增加100等等.

我的问题是,在vector::resize()和之间做出选择vector::reserve().在这种情况下还有更好的选择吗?

编辑:我有一些精确的估计t_Names.我估计它要700到了800.然而,在某些(很少)情况下,它可以增长超过1000.

Jan*_*dec 243

这两个功能完全不同!

resize()方法(和传递参数的构造等同于)将插入或删除元素的适当数量的矢量,从而使它给定的大小(它必须指定它们的值可选的第二个参数).它会影响size(),迭代将遍历所有那些元素,push_back将在它们之后插入并且你可以使用它直接访问它们operator[].

reserve()方法仅分配内存,但保留未初始化.它只影响capacity(),但size()不会改变.对象没有值,因为向量中没有添加任何内容.如果然后插入元素,则不会重新分配,因为它是事先完成的,但这是唯一的效果.

所以这取决于你想要什么.如果您想要一个包含1000个默认项的数组,请使用resize().如果您想要一个阵列,您希望插入1000个项目,并希望避免一些分配,请使用reserve().

编辑: Blastfurnace的评论让我再次阅读这个问题并意识到,在您的情况下,正确的答案是不要手动预分配.只需根据需要在元素末端插入元素即可.向量将根据需要自动重新分配,并且比上述手动方式有效.唯一reserve()有意义的情况是,您需要提前轻松获得所需总尺寸的合理精确估计.

EDIT2:广告问题编辑:如果您有初步估算,那么reserve()估算.如果事实证明还不够,那就让矢量做吧.

  • 实际上,在推动之前保留是至关重要的,必须使用.假设您正在编写某种类型的3D模型加载器,并且该模型具有15000个顶点.如果你尝试在加载时push_back每个顶点而不先预先分配它们,那将花费很多时间.我个人经历过这一点,我试图加载一个近100000个顶点的汽车.obj模型,耗时30秒.然后我使用.reserve()预分配重构代码,现在需要3秒.只需在代码开头放一个.reserve(100000)就可以节省27秒. (17认同)
  • 你的措辞对已经知道正确答案的人有意义,但很容易误导需要提问的人."resize()...会将给定数量的元素插入到向量中" - 仅在第一次使用时才为true - 它通常会插入所请求的数字与预先存在的`size()`之间的差异."reserve()方法只分配内存" - 它可能会也可能不会分配内存,具体取决于`capacity()`是否足够,它可能还需要移动元素并释放它们的原始内存."想要避免一些分配"和副本等 (4认同)
  • @Jan:嗯,根据你为自己维持所需财产的难度而言,这很脆弱.像`x.reserve(x.size()+ newdata)之类的东西; vector <int> :: iterator special_element = get_special_element(x); for(int i = 0; i <newdata; ++ i){if some_function(i,special_element)x.push_back(i); 就保留空间而言,它是非常强大的.我不知道实际会添加多少元素,但我有一个上限.当然,如果有疑问,使用索引而不是迭代器,差异通常可以忽略不计. (3认同)
  • @deniz,这在 100000 规模上是微不足道的,但在 100-300 规模上则不然,如果不必要地进行保留,可能会造成浪费。 (2认同)

Naw*_*waz 27

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
Run Code Online (Sandbox Code Playgroud)

输出(在线演示):

1
1
0
1
Run Code Online (Sandbox Code Playgroud)

resize()如果您不想要默认创建的对象,那么可能并不可取.它也会很慢.此外,如果您有push_back()新元素,则通过分配新内存(这也意味着将现有元素移动到新分配的内存空间)size()将进一步增加向量.如果你在开始时已经使用过来确保已经有足够的已分配内存,那么当你使用它时,向量会增加,但是在它为你保留的空间用完之前它不会再分配新的内存.reserve()size()push_back()

  • @iammilind:不,如果索引大于或等于`v.size()`.注意`reserve(N)`不会改变向量的'size()`. (16认同)
  • 做`reserve(N)`后,我们可以无害地使用`operator []`.对吗? (6认同)
  • @iammilind:不正确.调用reSERVE后,不添加任何条目,只获得足够的内存来添加它们. (5认同)
  • 虽然大多数实现会分配您通过 `reserve` 请求的确切数量,但规范只要求它至少分配那么多,因此某些实现可能会四舍五入到某个边界,从而显示出比 1000 更高的容量。 (2认同)