【问题标题】:In C++, will the vector function push_back increase the size of an empty array?在 C++ 中,向量函数 push_back 会增加空数组的大小吗?
【发布时间】:2011-12-08 03:56:32
【问题描述】:

快速提问。假设我声明了一个大小为 20 的向量。然后我想使用 push_back 向它添加一些整数。

vector<int> myVector(20);
myVector.push_back(5);
myVector.push_back(14);

我的向量的容量现在是 22,还是仍然是 20?是否分别将 5 和 14 添加到索引 [19] 和 [20] 中?还是他们在 [0] 和 [1]?

【问题讨论】:

  • 不要犹豫,自己尝试一下

标签: c++ vector push-back


【解决方案1】:

在这些语句之后,它的容量由实现定义。 (请注意,这与它的大小不同。)


vector<int> myVector(20);

这将创建一个用 20 个 0 填充的向量。它的大小正好是二十个,它的容量至少是二十个。是否正好是 20 是实现定义的;它可能有更多(实际上可能没有)。

myVector.push_back(5);

此后,数组的第 21 个元素为 5,容量再次由实现定义。 (如果之前容量正好是 20,那么现在会以未指定的方式增加。)

myVector.push_back(14);

同样,现在数组的第 22 位元素是 14,容量是实现定义的。


如果你想保留空间,但不插入元素,你可以这样做:

vector<int> myVector;
myVector.reserve(20); // capacity is at least twenty, guaranteed not
                      // to reallocate until after twenty elements are pushed

myVector.push_back(5); // at index zero, capacity at least twenty.
myVector.push_back(14); // at index one, capacity at least twenty.

【讨论】:

  • 请注意,C++03 标准 23.2.4/1 要求 vectors “支持 (amortized) constant time 在末尾插入和擦除操作”,所以实际上,当push_back() 需要更多空间时,容量通常会扩大两倍。
  • 好的。谢谢你。我不知道它会充满 20 个 0。那真的会把我的程序搞砸了。我不知道为什么我不考虑不指定尺寸,因为它们是动态的,这就是我需要的。代表我的一个笨蛋。
【解决方案2】:
  • size 是向量容器中的元素个数。
  • capacity是分配的存储空间大小
  • push_back 有效地将向量大小增加一,如果向量大小等于调用前的向量容量,这会导致内部分配的存储重新分配。

更多信息:http://www.cplusplus.com/reference/stl/vector/

【讨论】:

    【解决方案3】:

    push_back 增加了std::vector 的大小,并将新元素放在vector 的后面(其他容器也有一个push_front 方法可以在前面做同样的事情)。

    但是,vector 的大小和容量之间存在差异。 size 指的是当前vector 中有多少项目; 容量 是指vector 在不重新分配内存的情况下可以容纳的项目总数。 reserve() 内存是可能的,如果你知道你要添加几个元素并且不想增加 vector 零碎。

    【讨论】:

    • 好的,所以 push_back 不会增加容量,对吧?除非该向量已经满负荷。
    • 正确,不一定会增加容量。我之所以提到它,是因为 std::vector 很难区分,所以保持术语的正确性很重要,尤其是在阅读 std::vector 的文档时。
    【解决方案4】:

    由于向量不为空,但大小为 20(包含 20 个元素),而您将 push 2 个元素添加到 back,它现在包含 22 个元素。但是新元素不是放在索引 19 和 20,而是 20 和 21。

    如果您真的只想为向量保留足够的内存以容纳 20 个元素(实际上不包含任何元素),以防止代价高昂的重新分配,那么您应该调用

    std::vector<int> myVector;
    myVector.reserve(20);
    

    在这种情况下,向量仍然是空的,但它有足够的内存来添加至少 20 个元素(例如使用push_back),而无需重新分配其内部存储空间。在这种情况下,向量仅包含您pushed_back 的 2 个元素。

    【讨论】:

    • 非常有帮助,谢谢。基本上我想要做的是创建一个向量,并且只在末尾添加元素。我没想到一开始我什至不必给出大小,因为向量是动态的。谢谢!
    【解决方案5】:

    push_back 将向量的容量增加到至少向量的新大小,但可能(即可能)更大一些。

    因为push_back 需要在 O(1) 摊销时间内运行,所以每次重新分配将是旧容量的某个倍数。在一个典型的实现中,倍数是 2。

    但未指定确切的容量增加。如果您需要精确控制容量,请使用reserve

    ...

    重新阅读您的问题,我不确定您是否理解向量大小和容量之间的区别。大小是元素的数量。容量是向量在不执行重新分配的情况下可以容纳的元素数。也就是说,您可以在重新分配发生之前push_back capacity()-size() 元素。

    在您的示例中,5 和 14 将分别出现在 myVector[20] 和 myVector[21] 中。

    【讨论】:

    • 对。我不明白的是,向量在创建它们时不需要容量,这就是它们的重点——它们是动态的,对吗?所以给他们一个初始容量是没有意义的。
    • @iaacp:不,这不是毫无意义的。如果您事先知道要在向量中放入多少东西,但在初始化向量时手头没有实际的东西,那么您可以reserve() 一个数量,这样vector 就不必进行任何重新分配。
    • @iiacp:如果你真的关心重新分配,这并不是没有意义的。重新分配 (a) 需要时间并且 (b) 使指向向量内元素的引用/指针无效。 reserve 允许您设置容量以避免将来重新分配。请注意,您的示例设置了向量的 size,而不是 capacity。您正在创建一个包含 20 个未初始化整数的向量。
    【解决方案6】:

    嗯,vector 有成员函数push_back。其他序列如dequepush_front

    0、1、2、……、最终

    添加后:

    0、1、2、......、最终、加法、......

    你可能还记得:

    capacity() returns the number of elements in the vector sufficient,
    without allocating additional memory.
    This number can be greater or equal to size.
    

    也就是说,您不能在前面或中间添加,因为vector 专门用于通过索引快速访问元素。如果要前后添加,可以使用deque,类似于vector。如果您想添加到前面、后面和任何可以使用list 的位置。请注意,list 不提供像 dequevector 这样的索引。

    但是,假定向量的容量大于其实际大小。当您向其中添加元素时,它不需要分配额外的内存。仅当容量等于大小时才会这样做。在许多编译器上,新容量将是旧容量的两倍。分配后,它会复制新位置中的所有元素。然而,这种行为在内存方面可能会很昂贵。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 2018-04-14
      相关资源
      最近更新 更多