证明 shrink_to_fit 或 swap 保证释放向量的内存 [重复]

Posted

技术标签:

【中文标题】证明 shrink_to_fit 或 swap 保证释放向量的内存 [重复]【英文标题】:Proof that shrink_to_fit or swap guarantees to release vector's memory [duplicate] 【发布时间】:2017-08-20 15:46:22 【问题描述】:

谁能证明以下方法之一可以保证以独立于平台的方式释放向量的内存?

vector<double> vec;
//populating vec here

清理:

1- 缩小以适应方法

vec.clear(); 
vec.shrink_to_fit();

2-交换方法

vector<double>().swap(vec);

【问题讨论】:

为什么你认为交换解决方案不会释放内存? 这是一个骗局 - 如果您想清空 a 向量,请使用交换成语,它使用标准的、记录在案的语言特性。 C++ 谈到了释放内存。释放的内存没有义务被“释放”,它只是变得无效。 shrink_to_fit 非常明确地拒绝提供解除分配的保证(这是一个非绑定请求)。 swap 也不保证。临时对象的销毁将可能释放其内存,但不再承诺(C++ 标准库 dtor 不保证释放任何内容或以其他方式无泄漏)。在这种情况和许多其他情况下,我们依靠实现来做正确的事情。 TimoGeusch 在下面的 cmets 中回答。这里的误解是空向量不分配内存。这不是真的。它没有在标准中指定,因此它可以是 0 或 4 或 256 或其他任何值。它是特定于实现的。当我们说“空闲内存”时,我们真正的意思是将其恢复到全新的构造状态。 @Robinson:是的。但它仅出于调试目的而这样做。并且它分配的内存不用于存储向量的元素。它用于跟踪迭代器。注意#if _ITERATOR_DEBUG_LEVEL == 0 包围的部分发生了什么。没有分配。 【参考方案1】:

使用new 创建vector 不太可能做我认为你想做的事情。

std::vector 实现通常只“保证”它们将分配足够的内存来至少保存所请求的元素数。后者很重要,因为当您需要增长向量时向操作系统或运行时请求更多内存是一项昂贵的操作,可能还会触发元素复制。出于这个原因,许多实现使用一些启发式方法来确定当向量必须增长到一定大小时分配的大小。例如,我熟悉的一种实现在每次需要新内存时将分配大小加倍,从而为您提供 2^x 分配模式。

使用这样的分配模式,尝试将向量从 90 个元素缩小到 70 个元素几乎可以保证保持分配的内存大小相同,以保留额外的增长空间。

如果您出于某种原因需要确切的内存分配大小,则几乎必须使用 std::array(如果您在编译时知道大小),或者自己管理数组。

【讨论】:

IIRC 许多向量实现使用不同的增长因子 @PasserBy,这绝对是依赖于实现的,并且可以依赖于它期望使用的运行时分配器。这就是为什么标准中没有定义向量的内存分配算法,它留给实现者,只有最低要求。 所以你的建议是任何给定的新向量都不能保证使用一些小的(微不足道的)内存,即使它的大小为零,所以“交换技巧”不会t 保证 size() == 0 && amount_of_memory_reserved == 0。至少标准中没有规定。 @Timo “这并不意味着没有为空向量保留零负载内存的实现。” - 这实际上是大多数实现所做的。这是 C++ 哲学的一部分——不用为不用的东西买单。 @Robinson 嗯,GCC 的容量为零,这是我希望一个好的实现能够做到的。但正如我们在这里多次观察到的那样,这不是标准化的......

以上是关于证明 shrink_to_fit 或 swap 保证释放向量的内存 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

等保三级认证备案证明是哪个机构颁发?一般要多久?

Iterator invalidation(迭代器失效)

shrink_to_fit

使用 shrink_to_fit() 释放向量向量中的内存

Linux Swap分区设定

使用零大小数组的 std::swap() 编译错误?