pop_back()能否减少向量的容量?(C++)

Kri*_*ege 7 c++ vector capacity c++11

根据C++标准,std::vector<T>::pop_back()是否允许减少向量的容量?

我问,因为我想保证,以下代码不会抛出内存不足异常:

my_vec.pop_back();
if (...)
    my_vec.push_back(...);
Run Code Online (Sandbox Code Playgroud)

假设my_vec是一个std::vector<int>.

我想有三种可能性:

  1. 是的,这可以根据C++ 03和C++ 11来实现.

  2. 不,C++ 11禁止这样做(但C++ 03没有).

  3. 不,C++ 03和C++ 11都禁止这样做.

是的,我的问题与std :: vector.pop_back()改变向量的容量有关吗?,但我的问题是关于标准保证的内容.

另请注意,在std :: vector.pop_back()中接受的答案会改变向量的容量吗?主要是关于如何减少向量的容量,而不是关于何时保证发生,并且没有提供关于pop_back()的声明的证据.

BoB*_*ish 8

根据http://en.cppreference.com/w/cpp/container/vector/pop_back

没有迭代器或引用,除了back()end()无效.

因此可能无法重新分配.C++11该页面上没有标记,这暗示在03中也是如此.我将挖掘部分引用并编辑它们以获得完整性.

编辑:更好:来自C++03:[lib.container.requirements](23.1),第10段:

erase(),pop_back()pop_front()函数抛出异常.

N3337(〜C++11)中23.2.1/10的措辞相同.

  • 请记住,它必须通过分配器,并且 [`std::allocator`](http://en.cppreference.com/w/cpp/memory/allocator) 没有任何类型的“重新分配” ` 成员。 (2认同)

gsa*_*ras 5

第萎缩向量的能力的唯一途径是交换技巧,如图所示这里.还有C++11我提到的方式.

此外,正如裁判所说:

移除向量中的最后一个元素,
有效地将容器大小减少一个.

换句话说,它改变了矢量的大小不是它的容量.

看看迭代器的有效性:

结束迭代器以及引用
已删除元素的任何迭代器,指针和引用都将失效.
引用
未被删除的其他元素的迭代器,指针和引用保证
在调用之前保持引用它们所指的相同元素.

C++11你可以使用std::vector<>::shrink_to_fit(),以改变的能力(更多见的第一个链接).(tnx Psyduck).有趣的评论下面的答案,但这个问题不是关于上述方法,所以如果有兴趣,请阅读评论.

请注意,即使这种方法也不能保证减少capacity,因为ref说:

请求容器减小其容量以适应其大小.

请求是非绑定的,并且容器实现可以自由地优化>并且使向量的容量大于其大小.

这可能会导致重新分配,但对矢量大小没有影响,并且不能更改其>元素.

奇怪的是,这个函数不能保证减少capacity和减少pop_back,而第二个函数的参考没有提到任何相关的东西.

我认为它的方式,因为参考没有提到capacity,这意味着它不需要,这意味着,它capacity保持不变.

一个有趣的例子是:

#include <iostream>
#include <vector>

int main() {
  const int N = 1000000;

  std::vector<int> v1;
  v1.reserve(N);
  for (int i = 0; i < N; ++i) {
    v1.push_back(i);
  }

  std::cout << v1.capacity() << " and size = " << v1.size() << std::endl;

  for (int i = 0; i < N - 2; ++i) {
    v1.pop_back();
  }

  std::cout << v1.capacity() << " and size = " << v1.size() << std::endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1000000 and size = 1000000
1000000 and size = 2
Run Code Online (Sandbox Code Playgroud)

哪里capacity显然没有减少.

[编辑]

另一个相关的问题,也可以被标记为重复,有一些很好的答案.这里有一些有趣的:

1)

去看看Scott Meyers Effective STL第17项.(OP看起来有些参考)基本上你不能直接减少std :: vector的存储大小."技巧"是>创建一个合适大小的新容器,复制数据并与当前容器交换.

2)

不,你不能在没有复制的情况下减少矢量的容量.

3)

我并不是说GCC没有一些方法可以在没有副本的情况下做你想做的事情,>但实现起来会很棘手(我认为)因为向量需要使用Allocator对象来分配和释放内存,分配器的接口不包含reallocate()方法.我不认为这是不可能的,但它可能会很棘手.

我建议阅读更多链接.

[EDIT.2]

这个问题也支持:

问:可以pop_back()减少capacity吗?

答:没有.

如果你不能依靠适当的方法来减少容量(根据你在标准中读到的内容),你不能指望pop_back()做那样的事情.

  • @MooingDuck`rink_to_fit`,但它是一个非绑定请求,所以不能保证收缩, (2认同)