这个嵌套数组是使用堆栈还是堆内存?

时间:2011-09-01 01:04:12

标签: c++

说我有这个声明并使用嵌套在矢量中的数组

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的内存怎么样?这是在堆栈上,即如果我的段太大,我应该担心吗?
还有最后一本书的记忆呢?那我必须在堆上,但嵌套数组在堆栈上,不是吗? 其他问题
Paragraph的记忆是否连续?
book的内存是连续的吗?

3 个答案:

答案 0 :(得分:6)

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

std::array<T,N>不使用任何动态分配,它是自动分配T[N]的包装物。

你在矢量中放置的任何东西都会由矢量自己的分配器分配,在默认情况下(通常)会使用::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]之外,数组没有理由包含任何数据1}},但我不确定这是否是强制性的。

你可能想问这个问题,这是一个很好的问题!

答案 1 :(得分:2)

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

答案 2 :(得分:1)

您的代码示例:

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 ++保证了一个抽象堆栈,并且在所有现存的计算机上保证抽象堆栈是用硬件辅助的类似数组的简单堆栈实现的

“向量para的内存怎么样?堆栈上的内容是什么” 同样,这取决于您未显示的声明上下文。而且,即使对象本身在堆栈上分配,它在内部引用的部分也不会(通常)在堆栈上分配。

“,即如果我的段落太大,我应该担心吗?” 不,没有必要担心。 std::vector动态分配其缓冲区。它不受可用堆栈空间的限制。

“最后还有什么关于书的内存?我猜这应该在堆上,但是嵌套数组在堆栈上,不是吗?” 不,不。

“Paragraph的内存是否连续?” 号。但是向量的缓冲区是连续的。这是因为std::array保证是连续的,并且std::vector的缓冲区保证是连续的。

“图书的记忆是否连续?” 没有