【问题标题】:Difference between std::resize(n) and std::shrink_to_fit in C++?C++ 中 std::resize(n) 和 std::shrink_to_fit 之间的区别?
【发布时间】:2020-06-09 13:11:14
【问题描述】:

我遇到了这些说法:

resize(n) – 调整容器的大小,使其包含“n”个元素。
shrink_to_fit() – 减小容器的容量以适应其大小并销毁超出容量的所有元素。

这些功能之间有什么显着区别吗?它们属于 C++ 中的向量

【问题讨论】:

  • resize 修改容器的大小,shrink_to_fit 不会。对于正常使用,您不需要了解 shrink_to_fit,它仅可让开发人员手动提高其代码的性能。
  • 标准容器有一个size和一个capacity。大小是容器中当前元素的数量,而容量是分配的内存量(大致)。调整大小改变大小,shrink_to_fit 改变容量。
  • 你了解capacity和size的区别吗?

标签: c++ c++11 vector containers capacity


【解决方案1】:

向量有两个“长度”属性,表示不同的含义:

  • size 是向量中可用元素的数量。这是您存储的东西的数量。这是一个概念长度。
  • capacity 是向量当前分配的内存量可以容纳多少元素。

capacity >= size 必须始终为真,但没有理由让它们始终相等。例如,当您删除一个元素时,缩小分配将需要创建一个小一个存储桶的新分配并将剩余的内容移到上面(“分配、移动、释放”)。

类似地,如果capacity == size 并且您添加了一个元素,则向量可以将分配增加一个元素(另一个“分配、移动、释放”操作),但通常您会添加多个元素。如果容量需要增加,向量会将其容量增加超过一个元素,这样您就可以在需要再次移动所有内容之前再添加几个元素。

有了这些知识,我们可以回答您的问题:

  • std::vector<T>::resize() 改变数组的大小。如果将其调整为小于其当前大小,则会破坏多余的对象。如果您将其调整为大于其当前大小,则最后添加的“新”对象将默认初始化。
  • std::vector<T>::shrink_to_fit() 要求更改 容量 以匹配当前大小。 (实现可能也可能不接受这个请求。他们可能会减少容量,但不会使其等于大小。他们可能根本不做任何事情。)如果请求得到满足,这将丢弃一些或向量分配的所有未使用部分。您通常会在完成构建矢量时使用它,并且永远不会向其中添加其他项目。 (如果您事先知道要添加多少项,最好在添加任何项之前使用std::vector<T>::reserve() 告诉向量,而不是依赖shrink_to_fit 做任何事情。)

所以你使用resize() 来改变向量中有多少东西在概念上。

您使用shrink_to_fit() 来最小化向量在内部分配的多余空间而不在概念上改变向量中有多少东西。

【讨论】:

  • 请注意,shrink_to_fit 不是全有或全无。一个实现可能会部分减少容量。例如,考虑一个将向量容量限制为 2 次方的实现。
【解决方案2】:

shrink_to_fit() – 减小容器的容量以适应其大小并销毁超出容量的所有元素。

这是对所发生事情的错误描述。具体地说,销毁所有超出容量的元素部分并不准确。

在C++中,当动态内存用于对象时,有两个步骤:

  1. 为对象分配内存。
  2. 对象在内存位置初始化/构造。

删除动态分配内存中的对象时,也有两个步骤,与构造步骤相同,但顺序相反:

  1. 内存位置的对象被破坏(对于内置类型,这是一个 noop)。
  2. 对象使用的内存被释放。

超出容器大小分配的内存只是缓冲区。它们没有任何正确初始化的对象。这只是原始记忆。 shrink_to_fit() 确保不存在额外的内存,但这些位置没有对象。因此,没有任何东西被破坏,只有内存被释放。

【讨论】:

    【解决方案3】:

    根据相对于shrink_to_fit的C++标准

    效果:shrink_to_fit 是减少容量的非绑定请求() 到大小()。

    相对于resize

    效果:如果 sz

    很明显,这些函数做了不同的事情。此外,第一个函数没有参数,而第二个函数甚至有两个参数。 shrink_to_fit 函数不会改变容器的大小,但可以重新分配内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-24
      • 2014-03-04
      • 2013-01-18
      • 2012-04-25
      • 2015-07-21
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多