在 std::vector 中释放内存

Memory deallocation in std::vector

本文关键字:释放 内存 vector std      更新时间:2023-10-16

我试图弄清楚当你删除元素时,std::vector 的内存管理是如何工作的。我的理解是,一旦为矢量分配了内存,任何 pop_back\erase 操作都不会降低矢量的容量,唯一的方法是使用 C++ 11 中引入的shrink_to_fit。如果我错了,请纠正我。

你说得对,大部分。

只有几种方法可以降低std::vector的容量...

移动分配

#include <iostream>
#include <vector>
int
main()
{
    std::vector<int> v1(10);
    std::vector<int> v2(20);
    std::cout << "v2.capacity() = " << v2.capacity() << 'n';
    std::cout << "Move assign v2 with less capacityn";
    v2 = std::move(v1);
    std::cout << "v2.capacity() = " << v2.capacity() << 'n';
}

应该输出:

v2.capacity() = 20
Move assign v2 with less capacity
v2.capacity() = 10

如果以某种方式设置所涉及的分配器,则无法保证容量减少。 但在上面显示的常见情况下,容量会缩小。 如果您真的想知道在移动分配期间容量如何不会缩小的细节,请问另一个问题,我可以详细研究。

shrink_to_fit

#include <iostream>
#include <vector>
int
main()
{
    std::vector<int> v(20);
    std::cout << "v.capacity() = " << v.capacity() << 'n';
    std::cout << "erasing...n";
    v.erase(v.begin() + v.size()/2, v.end());
    std::cout << "v.capacity() = " << v.capacity() << 'n';
    std::cout << "shrink_to_fit...n";
    v.shrink_to_fit();
    std::cout << "v.capacity() = " << v.capacity() << 'n';
}

这可能会输出:

v.capacity() = 20
erasing...
v.capacity() = 20
shrink_to_fit...
v.capacity() = 10

但它允许输出:

v.capacity() = 20
erasing...
v.capacity() = 20
shrink_to_fit...
v.capacity() = 20

交换

#include <iostream>
#include <vector>
int
main()
{
    std::vector<int> v(20);
    std::vector<int> v2(10);
    std::cout << "v.capacity() = " << v.capacity() << 'n';
    std::cout << "swap...n";
    swap(v, v2);
    std::cout << "v.capacity() = " << v.capacity() << 'n';
}

应该输出:

v.capacity() = 20
swap...
v.capacity() = 10

我知道没有其他方法可以缩小vector的容量(除了明显等效的结构,例如v.swap(v2))。

一个好的经验法则是,矢量的容量永远不会缩小,除非:

  1. 它使用另一个向量传输资源(例如移动分配或swap)。
  2. shrink_to_fit被称为。

哦,我差点忘记了第三种可能性:任何时候你vector移动时,从vector移动的容量可能会减少(或者可能不会)。 它是未指定的,因此您不能指望它。 通常,移自值应该是您不关心其当前状态的变量。 随后,您将销毁它们或为它们分配一个新的已知状态(赋值不必通过赋值运算符;例如,可以clear()后跟push_back())。