【问题标题】:size vs capacity of a vector?向量的大小与容量?
【发布时间】:2023-04-02 18:55:01
【问题描述】:

我对此有点困惑,这两个对我来说看起来都一样。 尽管可能会发生容量和大小在不同编译器上可能不同的情况。它可能有何不同。 它还说如果我们内存不足,容量就会改变。

所有这些我都不清楚。

有人可以解释一下吗?(如果可能的话,可以举个例子,或者我可以对任何程序进行任何测试以理解它)

【问题讨论】:

标签: c++ vector


【解决方案1】:

大小 不允许在多个编译器之间有所不同。向量的大小是它包含的元素的数量,它直接由你放入向量中的元素数量控制。

Capacity 是向量拥有的总空间量。在引擎盖下,向量只使用一个数组。向量的容量是该数组的大小。这总是等于或大于大小。它们之间的区别在于,在需要重新分配引擎盖下的数组之前,您可以添加到向量中的元素数量。

您几乎不应该关心容量。它的存在是为了让具有非常特定的性能和内存限制的人做他们想做的事。

【讨论】:

  • +1 对我来说很清楚,而且还有额外的小鬼。 info-->“你几乎不应该关心容量。它的存在是为了让具有非常特定的性能和内存限制的人完全按照他们想要的方式去做。”谢谢
  • 不同意不关心容量。如果您知道您的向量中至少要存储 200 个项目,那么在构建时不告诉它您会发疯的。
  • 疯了吗?我不一定这么认为。我刚刚运行了一些测试,插入了 200 个 ints 有和没有保留空间,我需要超过 100,000 次重复才能显示出显着的性能改进。诚然,在保留空间时性能大约是原来的两倍,但除非你在一个紧密的循环中这样做并且这是你的性能瓶颈,否则我真的不认为不太关心几微秒是疯狂的.
  • @John:所以即使知道可能会重新分配,您仍然不会将单个已知数字传递给构造函数以防止所述重新分配?我支持我的“疯子”。即使在现代机器上使用整数(最佳案例场景测试),我也会这样做以使代码的意图更清晰,更不用说嵌入式系统上的更大结构。
  • @Kent:我不同意这个原则。我认为,如果您处于非常具体的情况,您对容器的最终用途有明确的了解,那么保留容量是一种很好的做法。这就是为什么我的回答中的“从不”为“几乎从不”。
【解决方案2】:

大小:当前向量中的项目数

容量:在向量“满”之前可以容纳多少项。填满后,添加新项目将导致分配一个新的、更大的内存块并将现有项目复制到其中

【讨论】:

  • 我会说不是分配而是重新分配。因为vector保证了数据在内存中连续布局,所以不能使用操作符new返回的多个内存块。因此,当达到限制时,vector 将分配一个新的内存块并将现有数据复制到该内存,然后删除先前分配的块。或者,如果它足够聪明,它会使用realloc 函数更优化一点。
  • @Vlad:我假设您在看到我的最后一次编辑之前发表了评论?
  • 感谢这个答案比接受的答案帮助我更容易理解它。我为将来的访问者创建了这个 pastebin 来回答这个问题:pastebin.com/Xx1RAc9K,这里的示例代码 cplusplus.com/reference/vector/vector/reserve 现在更清晰了。
【解决方案3】:

假设你有一个桶。这个桶最多可以装5加仑的水,所以它的容量是5加仑。它可以含有 0 到 5 之间的任何水量,包括 0 和 5。当前在桶中的水量,用向量表示,就是它的大小。所以如果这个桶是半满的,它的大小是 2.5 加仑。

如果您尝试向桶中添加更多的水并且它会溢出,您需要找到一个更大的桶。所以你得到一个容量更大的桶,把旧桶里的东西倒进新桶里,然后加入新水。

容量:Vector/bucket 可以容纳的最大容量。 大小:当前在 Vector/bucket 中的东西的数量。

【讨论】:

  • 您必须是一名讲师。我无法准确理解分配内存的含义,但我现在完全理解它的确切含义。
  • 这是一个非常棒的类比!向量就是水桶!
  • 这个解释是完全错误的。我将一个空向量的大小调整为 3,大小和容量都为 3。我还没有放任何东西。
  • @eigenfeld 但是如果你将一个空向量reserve() 为3,则大小为0,容量为3。
【解决方案4】:

大小是向量中元素的数量

容量是向量当前使用的空间量。

让我们通过一个非常简单的例子来理解它:

using namespace std;

int main(){
  vector<int > vec;
  vec.push_back(1); 
  vec.push_back(1); 
  vec.push_back(1); 
  cout<<"size of vector"<<vec.size()<<endl;
  cout<<"capacity of vector"<<vec.capacity()<<endl;
  return 0;
}

当前大小为 3 和 容量为 4。

现在,如果我们再推回一个元素,

using namespace std;
  int main(){
  vector<int> vec;
  vec.push_back(1); 
  vec.push_back(1); 
  vec.push_back(1); 
  vec.push_back(1);
  cout<<"size of vector"<<vec.size()<<endl;
  cout<<"capacity of vector"<<vec.capacity()<<endl;
  return 0;
}

现在 尺寸为:4 容量为 4

现在如果我们尝试在vector 中再插入一个元素,那么大小将变为 5,但容量将变为 8。

它基于vector 的数据类型发生,在本例中vector 类型为int,因为我们知道int 的大小为4 个字节,因此编译器将分配4 个内存块。当我们尝试添加第 5 个元素时,vector::capacity() 是我们目前拥有的两倍。

同样继续..例如:如果我们尝试插入第 9 个元素,则 vector 的大小将为 9,容量为 b 16..

【讨论】:

  • 我认为您对容量为何翻倍的解释含糊不清。容量返回的数字是关于我们可以在重新分配之前添加的“元素”的数量,而不是字节。包含两个数字的整数向量的容量为 2,如果这 2 以字节为单位,那么即使单个整数也无法放入向量中。也许我错过了一点。你能更清楚地解释为什么容量翻倍吗?
  • 我的问题更严重。无论我添加多少元素,MSVC 都会返回相同的数字?
  • 我使用的是 MS VStudio 17,但在所有情况下我的大小和容量都相同
【解决方案5】:

size() 告诉你当前有多少元素。 capacity() 告诉您在向量需要为自己重新分配内存之前,大小可以达到多大。

容量总是大于或等于大小。您不能索引超出元素 #size()-1

【讨论】:

    【解决方案6】:

    大小是向量中元素的数量。容量是向量当前可以容纳的最大元素数。

    【讨论】:

      【解决方案7】:

      向量大小是向量的元素总数,并且对于所有编译器始终相同。向量可以重新调整大小。

      容量是向量当前可以容纳的最大元素数。不同的编译器可能会有所不同。

      容量会根据需要更改,或者您可以设置初始容量,并且在达到该容量之前不会调整大小。它会自动展开。

      容量 > = 大小

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多