繁体   English   中英

std :: vector在哪里分配其内存?

[英]Where does a std::vector allocate its memory?

考虑以下代码片段:

#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 :: vector是否在堆上为其元素分配内存? 但是如何释放堆内存呢? 如果它是堆栈上的局部向量,则包含该向量的函数的堆栈框架最终会被删除,而不会向该向量发出将其删除的信号?

std :: vector是否在堆上为其元素分配内存?

是。 或更准确地说,它基于您在构造时传递的分配器进行分配。 您没有指定一个,所以您获得了默认分配器。 默认情况下,这将是heap

但是如何释放堆内存呢?

通过其析构函数超出范围时。 (请注意, 指向向量的指针超出范围不会触发析构函数)。 但是,如果您已按值将值传递给sub可以构造(然后销毁)新副本。 然后将5推回到该副本上,副本将被清理,并且main的向量将保持不变。

STL中的所有容器都使用模板参数进行参数化,通常最后一个参数称为AAllocator ,默认为std::allocator<...> ,其中...表示容器内存储的值的类型。

Allocator是用于提供内存和构建/销毁此内存区域中的元素的类。 它可以从池中分配内存,也可以直接从堆中分配内存,无论您从中构建分配器。 默认情况下, std::allocator<T>::operator new的简单包装,因此将根据您的推断在堆上分配内存。

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

像所有局部变量一样,析构函数在执行到达声明其作用域的末尾时调用。 因此,在函数退出之前,将调用向量析构函数,并且只有在此之后,堆栈才会收缩,并且控制权返回给调用者。

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

因为您为sub提供了堆中向量的地址,所以它将在堆中分配。 如果没有剩余空间,则应引发异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM