堆栈溢出 - 静态内存与动态内存

Posted

技术标签:

【中文标题】堆栈溢出 - 静态内存与动态内存【英文标题】:Stack overflow - static memory vs. dynamic memory 【发布时间】:2011-04-25 04:57:54 【问题描述】:

如果你在 C/C++ 的 main 函数中写 int m[1000000]; ,它会得到一个堆栈溢出的运行时错误。相反,如果你写 vector<int> m; 然后 push_back 1000000 那里的元素,它会运行良好。

我很好奇为什么会这样。它们都是本地内存,不是吗?提前致谢。

【问题讨论】:

Is there a max array length limit in C++? 的可能重复项 “本地”内存是什么意思? 你的问题是关于“C/C++”,但是你不能用C写vector。“vector”是一个隐藏底层内存管理复杂性的C++类。 【参考方案1】:

是的,向量本身是一个自动(堆栈)对象。但是向量包含一个指向其内容的指针(一个内部动态数组),并且将在堆上分配(默认情况下)。为了简化一点,您可以将vector 视为在内部执行malloc/reallocnew[] 调用(实际上它使用allocator)。

编辑:正如我所指出的,自动变量在堆栈上分配,而malloc 通常在堆上分配。每个平台的可用内存都因平台甚至配置而异,但可用堆栈内存通常更多受到更多限制。

【讨论】:

您忘记解释堆与堆栈的大小限制。 malloc / realloc / new 都是花花公子,但它们实际上并没有解释任何东西.. @matthew-flaschen :这可能有点不相关,但我有一个问题。现在,如果我想为这些类提供自定义分配器并且它们将具有不同的大小(当然),我必须使用放置新并覆盖新/删除。现在正常的内存管理器变得支离破碎,所以我在这里发布了一个问题,***.com/questions/3920453/…。 @ianmac45,问题是它们是否都是“本地内存”。正如我所解释的,vector 使用堆(“非本地”)内存。我会详细说明尺寸问题。【参考方案2】:

int m[1000000] - 它将在堆栈上分配 1000000 个整数。由于堆栈是有限的,所以它会抛出堆栈溢出运行时错误。

向量 m;然后 1000000 个元素的 push_back 正在工作,因为 内部向量在堆上而不是在堆栈上分配内存。所以在您的应用程序堆栈中只有矢量对象存在,因此它不会引发堆栈溢出运行时错误。

【讨论】:

【参考方案3】:

堆栈内存的数量是有限的,因为它必须提前保留。但是,堆内存量通常会消耗到操作系统施加的更高限制,但“几乎”会达到虚拟地址空间的限制(32 位机器为 2GB,64 位机器要多得多)机器)。

您可以增加保留的堆栈空间量,通常作为链接器的设置。

【讨论】:

你忘了说这是系统特定的。在 GNU/Linux 上,您可以使用 ulimit -s 在执行前增加堆栈大小。【参考方案4】:

向量对象本身在栈上;但在内部,它将根据需要从堆中分配内存以存储任意数量的元素。所以堆栈成本很小并且是固定的。

【讨论】:

以上是关于堆栈溢出 - 静态内存与动态内存的主要内容,如果未能解决你的问题,请参考以下文章

初识JVM堆栈

怎么解决 LINUX 堆栈溢出内存的问题

缓冲区溢出详解

在发生堆栈溢出之前剩余堆栈的大小

什么是堆栈溢出?

Java堆栈溢出的机制与原理