是否使用堆栈或堆内存的嵌套数组

Is this nested array using stack or heap memory?

本文关键字:内存 嵌套 数组 堆栈 是否      更新时间:2023-10-16

假设我将数组的声明和使用嵌套在向量中

const int MAX_LEN = 1024;
typedef std::tr1::array<char, MAX_LEN> Sentence;
typedef std::vector<Sentence> Paragraph;
Paragraph para(256);
std::vector<Paragraph> book(2000);

我假设Sentence的内存在堆栈上。
是这样吗?向量para的内存呢?它在堆栈上吗,也就是说,如果我的para变大了,我应该担心吗?
最后关于书本的记忆呢?我猜它应该在堆上但嵌套数组在堆栈上,不是吗?
额外的问题
Paragraph的内存是连续的吗?
book的内存是连续的吗?

没有堆栈。不要考虑堆栈。重要的是给定的容器类是否执行任何动态分配。

std::array<T,N>不使用任何动态分配,它是对自动分配的T[N]的一个非常好的包装。

vector 中的任何内容都将由vector自己的分配器分配,在默认情况下(通常)使用::operator new()执行动态分配。

所以简而言之,vector<array<char,N>>vector<int>非常相似:分配器只是为array<char,N>(或int)的多少个单元分配内存,因为它需要保存和构造该内存中的元素。冲洗并重复嵌套向量。


对于您的"附加问题":vector<vector<T>>绝对不与T相邻。它仅仅对vector<T>是连续的,但是只有包含了内部向量的小簿记部分。内部向量的实际内容由内部向量的分配器分配,并且为每个内部向量单独分配。一般来说,vector<S>S类型是连续的,没有其他。

我实际上不确定vector<array<U,N>> -它可能是连续的U,因为数组没有理由包含任何数据除了包含U[N],但我不确定这是否是强制性的。

你可能想把它作为一个单独的问题来问,这是一个好问题!

作为旁注,使用gdb可能会有所帮助。它允许您手动检查内存,包括变量的位置。

您的代码示例:

const int MAX_LEN = 1024;
typedef std::tr1::array<char, MAX_LEN> Sentence;
typedef std::vector<Sentence> Paragraph;
Paragraph para(256);
std::vector<Paragraph> book(2000);

"我假设句子的内存在堆栈上。对吗?" 。是否在堆栈上分配某些内容取决于声明上下文。你省略了上下文,因此什么也说不出来。如果对象是局部的且是非静态的,那么您将获得对象本身的堆栈分配,但不一定是它在内部引用的部分。顺便说一下,由于这里的另一个答案声称"没有堆栈",所以请忽略关于c++必须支持哪种系统的都市传说。它最初来自于对一个相当不成功的硬件级优化计算机的工作方式的误解,一些人错误地认为它没有一个简单的硬件支持的类似数组的堆栈实现。从"不简单"到"不存在"是一个相当大的延伸,甚至"不简单"都是完全错误的,不仅在事实上,而且在逻辑上(最终是自相矛盾的)。也就是说,这是一个不太聪明的初学者所犯的错误,尽管这个神话已经被至少一个有经验的人传播了。无论如何,c++保证了抽象堆栈,并且在所有现存的计算机上,保证了抽象堆栈的实现都是基于硬件辅助的数组——类似于简单堆栈

" vector para的内存是多少?在栈上吗?同样,这取决于您没有显示的声明上下文。同样,即使对象本身在堆栈上分配,它内部引用的部分也不会(通常)在堆栈上分配。

例如

"。如果我的裤子变大了,我应该担心吗?" 不,没有必要担心。std::vector动态分配它的缓冲区。不受可用堆栈空间的限制

"最后关于book的内存呢?我猜它应该在堆上但嵌套数组在堆栈上,不是吗?"

"是段连续的内存吗?"。但是这个向量的缓冲区是连续的。这是因为std::array是保证连续的,而std::vector的缓冲区是保证连续的。

" book的内存是连续的吗?"