C++ STD 容器:std::vector - 有没有办法清除向量并保留存储分配?

Posted

技术标签:

【中文标题】C++ STD 容器:std::vector - 有没有办法清除向量并保留存储分配?【英文标题】:C++ STD Containers: std::vector - Is there a way to clear the vector and retain storage allocation? 【发布时间】:2020-09-18 17:15:33 【问题描述】:

有没有办法在保留内存分配的同时清除std::vector的内容?

原因是我有一段循环的代码,我希望对其进行优化。我目前有数据存储在std::vectors。每次循环开始时,都应该清除向量的内容。然后我使用push_back 将数据输入到向量中,但是由于向量的长度在循环的迭代之间通常不会改变,因此我希望向量在内存中保留其分配的存储空间。

如果 vector 无法做到这一点,是否可以使用另一种快速访问 STD 类型?

【问题讨论】:

这能回答你的问题吗? ***.com/questions/18467624/… 我只是通过点击下面对 cppreference 的答案中的链接以及该页面链接到答案的链接找到了它。事实证明它可以很好地复制 如果向量大小没有改变,你是否考虑过完全不清晰?只保留旧元素并覆盖它们 .clear() 清除容器并将.size() 设置为零,但不会减少.capacity() 【参考方案1】:

有没有办法在保留内存分配的同时清除std::vector的内容?

是的,您调用std::vector::clear() 方法,正如documentation 中所述:

保持向量的容量()不变

【讨论】:

哇 cppreference 链接到一个 SO 答案。真是出乎意料。 啊,我一定是看错了文档。我以为它说clear() 将容量减少到零 - 但似乎我将大小与容量混淆了。 我认为 cppreference 在这方面可能是错误的。这在实践中绝对是正确的,但我并不是说这种行为实际上是必需的。您在 cppreference 上引用的注释引用了一个不太令人信服的 SO 答案,因为它似乎假设了结论。这一切都取决于vector::reserve 中的一个要求,但是用于证明capacity 没有在clear 中改变的那段段落的解释似乎是站不住脚的。我觉得这一切有点令人惊讶。我认为这条规则在标准中很明确,但事实并非如此。【参考方案2】:

先看这里:

Does clearing a vector affect its capacity?

所以标准似乎并没有规定容量在清除后保持不变。但在实践中通常会这样做。

但是你可以做两件事:

    在循环开始时对向量使用 reseve,这样每个循环只有一个分配。这很简单。 您可以以索引方式使用您的向量。这似乎更理想,但更难做到。

更新:这里提供的答案有问题:

What does the standard say about how calling clear on a vector changes the capacity?

答案中的理由是基于此: 在调用 reserve() 后发生的插入过程中不会发生重新分配 直到插入会使向量的大小大于 capacity() 的值。

这是在 C++ 标准中。

你可以试试这个:

v.reserve(v.capacity());
v.clear();

但是标准没有说明容量是否被clear改变,也没有说明reserve子句是指reseve调用时的容量,还是insert时的容量。

更新:有关 C++ 标准委员会讨论板上有关此问题的相关讨论,请参阅:https://cplusplus.github.io/LWG/issue1102

【讨论】:

这个答案声称容量保证不会改变:***.com/questions/18467624/… @idclev463035818 我找不到这样的保证。从C++11 standard 到C++20 standard,clear 函数仅受SequenceContainer 概念的要求约束——这只要求元素被销毁,并且复杂性是线性的。没有这样的段落限制容量改变 从技术上讲,是否允许更改容量是未指定的,据我所知,这并不意味着这样做是无效的 @Human-Compiler 我也不相信这个答案。 std::vector::clear 的 cppreference 页面链接到该答案。这当然不代表它是正确的,但是我对真相的寻找以一个圆圈结束,所以我没有进一步看...... @Human-Compiler size 的定义要求它在inserterase 发生时发生变化。它被定义为std::distance(a.begin(), a.end())inserterase 都改变了这个范围。编辑:虽然capacity 的概念确实没有这样的一般定义,但只有capacity() 定义了该术语。因此,只要不违反其他要求,它就可以因任何原因而改变。

以上是关于C++ STD 容器:std::vector - 有没有办法清除向量并保留存储分配?的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL应用与实现2: 如何使用std::vector

C++ STL应用与实现2: 如何使用std::vector

C++ STL应用与实现2: 如何使用std::vector

C++ Vector容器查找最大值,最小值以及相应的索引位置

C++ Vector容器查找最大值,最小值以及相应的索引位置

C++ Vector容器查找最大值,最小值以及相应的索引位置