简体   繁体   English

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

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

Consider the following code snippet: 考虑以下代码片段:

#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;
}

Assuming "vec" has no space left to store the 5 in the "sub" function, where does it allocate new memory? 假设“ vec”在“ sub”函数中没有剩余空间来存储5,它将在哪里分配新的内存?

In the stack frame of the sub function? 在子功能的堆栈框架中? In that case the 5 would be deleted at the end of the sub function. 在这种情况下,5将在子函数的末尾删除。 But the stack frame of the main function can't grow, as the stack frame of the sub function lies on top of the stack at that moment. 但是主函数的堆栈框架无法增长,因为此时子功能的堆栈框架位于堆栈的顶部。
Does a std::vector allocate memory for its elements on the heap? std :: vector是否在堆上为其元素分配内存? But how does it free that heap memory? 但是如何释放堆内存呢? If it's a local vector on the stack, the stack frame of a function including the vector is deleted in the end without signaling the vector that it will be deleted? 如果它是堆栈上的局部向量,则包含该向量的函数的堆栈框架最终会被删除,而不会向该向量发出将其删除的信号?

Does a std::vector allocate memory for its elements on the heap? std :: vector是否在堆上为其元素分配内存?

Yes. 是。 Or more accurately it allocates based on the allocator you pass in at construction. 或更准确地说,它基于您在构造时传递的分配器进行分配。 You didn't specify one, so you get the default allocator. 您没有指定一个,所以您获得了默认分配器。 By default, this will be the heap . 默认情况下,这将是heap

But how does it free that heap memory? 但是如何释放堆内存呢?

Through its destructor when it goes out of scope. 通过其析构函数超出范围时。 (Note that a pointer to a vector going out of scope won't trigger the destructor). (请注意, 指向向量的指针超出范围不会触发析构函数)。 But if you had passed by value to sub you'd construct (and later destruct) a new copy. 但是,如果您已按值将值传递给sub可以构造(然后销毁)新副本。 5 would then get pushed back onto that copy, the copy would be cleaned up, and the vector in main would be untouched. 然后将5推回到该副本上,副本将被清理,并且main的向量将保持不变。

All containers in the STL are parameterized with template arguments, usually the last argument is called A or Allocator and defaults to std::allocator<...> where ... represents the type of the value stored within the container. STL中的所有容器都使用模板参数进行参数化,通常最后一个参数称为AAllocator ,默认为std::allocator<...> ,其中...表示容器内存储的值的类型。

The Allocator is a class that is used to provide memory and build/destroy the elements in this memory area. Allocator是用于提供内存和构建/销毁此内存区域中的元素的类。 It can allocate memory from a pool or directly from the heap, whichever you build the allocator from. 它可以从池中分配内存,也可以直接从堆中分配内存,无论您从中构建分配器。 By default the std::allocator<T> is a simple wrapper around ::operator new and will thus allocate memory on the heap as you inferred. 默认情况下, std::allocator<T>::operator new的简单包装,因此将根据您的推断在堆上分配内存。

The memory is allocated on demand, and is deallocated at the very least when the vector 's destructor is called. 内存是按需分配的,至少在调用vector的析构函数时才释放。 C++11 introduces shrink_to_fit to release memory sooner too. C ++ 11也引入了shrink_to_fit来更快地释放内存。 Finally, when the vector outgrow its current capacity, a new (larger) allocation is made, the objects are moved to it, and the old allocation is released. 最后,当向量超出其当前容量时,将进行新的(较大)分配,将对象移至该分配,并释放旧的分配。

As will all local variables, the destructor is called when executed reaches the end of the scope it has been declared into. 像所有局部变量一样,析构函数在执行到达声明其作用域的末尾时调用。 So, before the function is exited, the vector destructor is called, and only afterward does the stack shrinks and control returns to the caller. 因此,在函数退出之前,将调用向量析构函数,并且只有在此之后,堆栈才会收缩,并且控制权返回给调用者。

Also note that your vector ( vec ) is object itself. 另请注意,向量( vec )是对象本身。 It resides on the stack and when this object goes out of scope (which is end of main in your case), it is destructed. 它驻留在堆栈上,并且当此对象超出范围(在您的情况下为main结尾)时,它将被破坏。 Memory for elements is allocated during initialization of this object and released with its destruction, which is a lovely example of RAII idiom, since the resource management of elements is tied to the lifespan of vector object. 元素的内存在此对象初始化期间分配,并随其销毁而释放,这是RAII惯用语的一个很好的示例,因为元素的资源管理与矢量对象的寿命相关。

Because you gave sub the adress of the vector in the heap, it will allocate in the heap. 因为您为sub提供了堆中向量的地址,所以它将在堆中分配。 If there's no space left, exception should be thrown. 如果没有剩余空间,则应引发异常。

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

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