【问题标题】:Is std::vector memory freed upon a clear?清除后是否释放了 std::vector 内存?
【发布时间】:2012-12-19 03:00:46
【问题描述】:

假设我有一个 std::vector 结构。如果向量是 clear()'d,内存会发生什么?

std::vector<myStruct> vecs;
vecs.resize(10000);
vecs.clear();

内存会被释放,还是仍然作为可重用缓冲区附加到 vecs 变量?

【问题讨论】:

  • 谢谢大家。我希望释放内存 - 保证。所以我使用 new std:vector 分配向量,然后在完成后调用 delete。因此保证内存被释放。
  • @AndrewS.:动态分配的唯一效果是引入了低效率。有关清空向量的合理方法,请参见 jerry 的答案。在循环体中,另一种好方法是只使向量局部于循环体,即在循环体中声明它。
  • 只是为了利益,内存为什么要保证免费?
  • 因为这是 ios 操作,我试图在更有限的平台上节省内存。

标签: c++ optimization memory vector


【解决方案1】:

内存仍然附着在向量上。这也不仅仅是可能的。这是必需的。特别是,如果您在调用 clear() 后再次向向量添加元素,则向量不得重新分配,直到您添加的元素数量超过之前的 1000 个。

如果你想释放内存,通常是用一个空向量交换。 C++11 还添加了一个shrink_to_fit 成员函数,旨在更直接地提供大致相同的功能,但它是非绑定的(换句话说,它可能会释放额外的内存,但仍然不需要这样做)。

【讨论】:

    【解决方案2】:

    向量的内存不能保证被清除。清除后您无法安全地访问元素。为了确保内存被释放,Scott Meyers 建议这样做:

    vector<myStruct>().swap( vecs );
    

    Cplusplus.com 对此有以下看法:

    从向量中删除所有元素,调用它们各自的 析构函数,使容器的大小为 0。

    向量容量不会改变,并且不会发生重新分配 调用这个函数。一个典型的替代方案,强制 重新分配是使用交换:...

    【讨论】:

    • 不保证清零吗?还是保证不被清零?这是两种截然不同的东西!
    【解决方案3】:

    在对象上调用析构函数,但内存仍然分配。

    【讨论】:

      【解决方案4】:

      不,内存没有被释放。

      在 C++11 中,您可以使用 shrink_to_fit 方法强制向量释放内存。

      http://www.cplusplus.com/reference/vector/vector/

      【讨论】:

      • 你可以使用它,但标准规定它不强制释放额外的内存(§23.3.6.3/6):“shrink_to_fit 是非绑定的请求将容量()减少到大小()。”
      • ... 因此,它与resize(0) 差不多,可能具有释放内存的副作用
      • 不,resize(0) 是 guaranteed to keep the memory。
      • resize(0) 最好不要有那个副作用!这将是多么糟糕的决定。
      【解决方案5】:

      .resize(0) 和 .clear() 不会释放或重新分配分配的内存,它们只是将向量大小调整为零大小,保持容量不变。

      如果我们需要通过释放(释放)内存来清除以下工作:

      Try it online!

      v = std::vector<T>();
      

      它调用= 运算符的&amp;&amp; 重载,该运算符执行移动,与swap() 解决方案类似。

      当存在= 运算符的&amp;&amp; 重载时,此分配技术有效,并且保证存在于所有 C++11 STD 库中,see here。因此,如果您使用 -std=c++11 (gcc/clang) 或 /std:c++11 (msvc) 开关(或更高版本)进行编译,我的解决方案可以保证工作。

      【讨论】:

      • 但问题是真的它需要吗?不只是发生在这段代码、编译器、设置等方面。为什么会Meyers 等人推荐 swap() 如果分配就足够了吗?
      • @underscore_d 是的,我的分配代码总是使用最近的编译器清除和释放内存。可能 Meyers 使用了 swap(),因为他的书很旧,当时没有 &amp;&amp; 右值参考。因为当没有= 运算符的&amp;&amp; 重载时,我的分配将不起作用,并且这种重载已经在所有STD 库中无处不在地出现了很多年。 &amp;&amp; 保证出现在所有 C++11 STD 库中,see here。
      猜你喜欢
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      • 2016-11-09
      相关资源
      最近更新 更多