C++ 在std::vector.reserve()之后在std::vector中重新分配

C++ 在std::vector.reserve()之后在std::vector中重新分配,c++,memory-management,C++,Memory Management,我有一段代码,首先将一些值放入std::vector中,然后将每个值的地址提供给将使用它们的一个对象,如下所示: std::vector < useSomeObject > uso; // uso is filled std::vector < someObject > obj; for (int i=0; i < numberOfDesiredObjects; ++i){ obj.push_back(someObject()); obj.ba

我有一段代码,首先将一些值放入
std::vector
中,然后将每个值的地址提供给将使用它们的一个对象,如下所示:

std::vector < useSomeObject > uso;

// uso is filled

std::vector < someObject > obj;

for (int i=0; i < numberOfDesiredObjects; ++i){
    obj.push_back(someObject());
    obj.back().fillWithData();
}
for (int i=0; i < numberOfDesiredObjects; ++i){
    uso[i].setSomeObject(&obj[i]);
}

// use objects via uso vector
// deallocate everything
for (int i=0; i < numberOfDesiredObjects; ++i){
    obj.push_back(someObject());
    obj.back().fillWithData();
    uso[i].setSomeObject(&obj.back());
}
std::vectoruso;
//uso已满
std::vectorobj;
for(int i=0;i
现在,因为我有时有点喜欢时尚,我觉得这很难看,我只想用1作为循环,有点像这样:

std::vector < useSomeObject > uso;

// uso is filled

std::vector < someObject > obj;

for (int i=0; i < numberOfDesiredObjects; ++i){
    obj.push_back(someObject());
    obj.back().fillWithData();
}
for (int i=0; i < numberOfDesiredObjects; ++i){
    uso[i].setSomeObject(&obj[i]);
}

// use objects via uso vector
// deallocate everything
for (int i=0; i < numberOfDesiredObjects; ++i){
    obj.push_back(someObject());
    obj.back().fillWithData();
    uso[i].setSomeObject(&obj.back());
}
for(int i=0;i
当然,我不能这样做,因为重新分配偶尔会发生,而且我设置的所有指针都变得无效

所以,我的问题是: 我知道,如果您知道需要多少内存并且希望提前分配内存,那么
std::vector.reserve()
就是一条出路。如果我使用
reserve()
确保我提前分配了足够的内存,这是否保证我的指针将保持有效

多谢各位


旁注。这是一个类似的问题,但我想知道的问题没有答案。只是为了防止它作为对这个问题的第一个评论突然出现

如果我使用reserve()确保预先分配足够的内存,这是否保证我的指针保持有效

是的,它保证您的指针将保持有效,除非:

  • 尺寸增加超过当前容量或
  • 除非,你删除了任何元素,而你没有
向量的迭代器无效规则在23.2.4.3/123.2.4.3/3中指定为:

插入点之前的所有迭代器和引用均不受影响,除非新容器大小大于以前的容量(在这种情况下,所有迭代器和引用均无效)

擦除点之后的每个迭代器和引用都无效


事实上,这是使用
reserve
的主要原因之一。你 保证不会在
std::vector
的末尾追加 使指向向量中元素的迭代器、引用或指针无效
只要向量的新大小不超过旧容量。

我教过的主要原因是尽量避免多次重新分配。如果这是原因的话,如果它没有成功,并且重新分配仍然进行,那么它不会造成太大的损害。因此,可以保证在
reserve()
失败的情况下,它会大声尖叫,而不仅仅是安静地继续程序。执行?@penelope:如果新大小大于当前容量(这是reserve确保满足您要求的容量),则将发生重新定位。@penelope
std::vector::reserve(n)
的post条件是
std::vector::capacity()>=n
。如果新的分配失败,您将得到一个异常。这不是问题所在。问题是,如果新的大小小于或等于当前容量,您是否保证不会发生重新分配(答案是肯定的)。请澄清,引发的异常通常是
std::bad_alloc
,考虑到
::正在使用新的
,而不是任何特殊的异常类型。标准库容器很少抛出它们自己的异常(
vector::at()
),它们通常只抛出它们所使用的标准库功能的异常以及抛出异常的异常。