提问者:小点点

std::向量在哪里分配内存?


考虑以下代码片段:

#include <vector>
using namespace std;

void sub(vector<int>& vec) {
    vec.push_back(5);
}

int main() {
    vector<int> vec(4,0);
    sub(vec);
    return 0;
}

假设“vec”没有剩余空间来存储“sub”函数中的5,它在哪里分配新内存?

在子函数的栈帧中?在这种情况下,5将在子函数的末尾被删除。但是主函数的栈帧不能增长,因为子函数的栈帧在那一刻位于堆栈之上。
std::向量是否为其堆上的元素分配内存?但是它如何释放堆内存?如果它是堆栈上的本地向量,则包含该向量的函数的栈帧最终被删除,而不会向向量发出将被删除的信号?


共3个答案

匿名用户

std::向量是否为堆上的元素分配内存?

是的。或者更准确地说,它根据您在构建时传入的分配器进行分配。您没有指定一个,因此您获得默认分配器。默认情况下,这将是堆。

但是它如何释放堆内存呢?

当它超出作用域时通过它的析构函数。(请注意,指向超出作用域的向量的指针不会触发析构函数)。但是如果您将值传递给sub,您将构建(然后销毁)一个新副本。5将被推回到该副本上,副本将被清理,main中的向量将保持不变。

匿名用户

STL中的所有容器都使用模板参数进行参数化,通常最后一个参数称为AAllocator,默认为std::allocator

Allocator是一个类,用于提供内存和构建/销毁此内存区域中的元素。它可以从池中或直接从堆中分配内存,无论您从何处构建分配器。默认情况下,std::allocator

内存是按需分配的,并且至少在调用向量的析构函数时被释放。C 11引入了shrink_to_fit来更快地释放内存。最后,当向量超出其当前容量时,进行新的(更大的)分配,将对象移动到其中,并释放旧的分配。

和所有局部变量一样,析构函数在执行到它被声明的范围的末尾时被调用。因此,在函数退出之前,向量析构函数被调用,只有在之后堆栈收缩并控制返回给调用者。

匿名用户

另请注意,您的向量(vec)是对象本身。它驻留在堆栈上,当该对象超出范围时(在您的情况下是main的末尾),它会被破坏。元素的内存在该对象的初始化期间分配并随其销毁而释放,这是RAII习惯用法的一个可爱示例,因为元素的资源管理与向量对象的生命周期相关联。