C ++中std :: resize(n)和std :: shrink_to_fit之间的区别?


11

我遇到了以下这些陈述:

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

这些功能之间有什么显着区别吗?他们在C ++中处于向量之下


resize修改容器的大小,而不使用rinkle_to_fit。对于正常用法,您无需了解rinke_to_fit,它仅可用于使开发人员能够手动提高其代码的性能。
NoSenseEtAl

2
标准容器具有大小容量。大小是容器中当前元素的数量,而容量是(大致)分配的内存量。调整大小会改变大小,会shrink_to_fit改变容量。
一些程序员老兄

2
你明白之间的差别capacitysize
立方

Answers:


12

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

  • 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()最小化向量在内部分配的多余空间,而无需更改向量中概念上的填充量。


2
请注意,这shrink_to_fit不是全部或全部。一个实现可能会部分减少容量。例如,考虑将向量容量限制为2的幂的实现。
弗朗索瓦·安德里厄

5

shrink_to_fit() –减小容器的容量以适应其尺寸,并破坏超出容量的所有元素。

那是对所发生事情的错误描述。具体而言,销毁超出容量部分的所有元素均不准确。

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

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

删除动态分配的内存中的对象时,还有两个步骤,它们以相反的顺序反映了构造步骤:

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

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


2

根据C ++标准 shrink_to_fit

效果:shrink_to_fit是一个非绑定请求,用于将Capacity()减小为size()。

和相对于 resize

效果:如果sz <size(),则从序列中删除最后一个size()-sz元素。否则,将sz-size()默认插入的元素追加到序列中。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.