C++ std::vector 在哪里分配内存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10366474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:57:44  来源:igfitidea点击:

Where does a std::vector allocate its memory?

c++memory-managementstlvector

提问by YoFrankie

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. 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? 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?

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

回答by Doug T.

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 destructorwhen it goes out of scope. (Note that a pointerto a vector going out of scope won't trigger the destructor). But if you had passed by value to subyou'd construct (and later destruct) a new copy. 5 would then get pushed back onto that copy, the copy would be cleaned up, and the vector in mainwould be untouched.

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

回答by Matthieu M.

All containers in the STL are parameterized with template arguments, usually the last argument is called Aor Allocatorand defaults to std::allocator<...>where ...represents the type of the value stored within the container.

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

The Allocatoris a class that is used to provide memory and build/destroy the elements in this memory area. 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 newand will thus allocate memory on the heap as you inferred.

Allocator是,用于提供存储器和构建/破坏在该存储器区域中的元素的类。它可以从池中或直接从堆中分配内存,无论您从哪个构建分配器。默认情况下,它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. C++11 introduces shrink_to_fitto release memory sooner too. 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.

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

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.

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

回答by LihO

Also note that your vector (vec) is object itself. It resides on the stack and when this object goes out of scope (which is end of mainin your case), it is destructed. Memory for elements is allocated during initialization of this object and released with its destruction, which is a lovely example of RAIIidiom, since the resource management of elements is tied to the lifespan of vector object.

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

回答by Stefan

Because you gave sub the adress of the vector in the heap, it will allocate in the heap. If there's no space left, exception should be thrown.

因为你给了 sub 堆中向量的地址,它会在堆中分配。如果没有剩余空间,则应抛出异常。