1

所以我明白什么是堆栈溢出,当内存发生冲突时(以及本网站的标题),但我不明白为什么堆栈的新条目位于递减的内存地址中。为什么它们不在随机内存地址中,这不是更有意义,因此内存冲突不是问题吗?我猜这背后有某种优化原因?

** 编辑 **

我没有意识到的是一个堆栈被赋予了 x 数量的地址空间。现在有道理,但让我想到了一个后续问题。我可以明确说明要分配给堆栈的内存量吗?

4

3 回答 3

3

“内存冲突”更适合“缓冲区溢出”的术语,即您在预定空间之外写入,但它可能位于不同的分配内存块内。

堆栈溢出不是关于将一​​个内存分配之外的内容写入另一个内存分配。这只是关于在堆栈内存分配之外进行写入。很可能在堆栈之外有一个保护内存页面,它没有分配给任何东西,这会导致读取或写入尝试出错。

并且为压入堆栈的每个值分配一个随机地址使得很难在堆栈上找到数据(并且它不再是堆栈)。当编译器或程序员知道后续元素占用后续地址时,只需从堆栈帧的基指针计算这些地址就很容易了。

于 2013-05-30T14:06:48.687 回答
1

这个问题的答案可能很复杂,但基本上堆栈操作被认为是处理器在正常执行代码时执行的非常原始的功能。(保存返回地址和其他东西。)

那么你把内存管理代码放在哪里呢?您在哪里跟踪分配的地址或添加代码以分配新地址?真的没有任何地方可以做到这一点,因为这些是处理器本身执行的基本操作。

与保存代码本身的内存类似,假设堆栈是在代码运行之前设置的(并由堆栈寄存器指向)。确实没有任何地方可以向堆栈内存添加复杂的内存管理。所以,是的,如果没有提供足够的内存,堆栈就会溢出。

于 2013-05-30T14:05:39.300 回答
1

堆栈溢出是指您已用完所有可用的堆栈空间。在大多数情况下,堆栈的可用空间只是系统设计人员选择的任意限制。可以改变这一点,但在现代系统上,这并不是一个真正的问题 - 需要几兆字节堆栈的代码,除非系统非常庞大,否则可能设计不正确。

堆栈从“自定义”向零增长 - 它必须朝着定义的方向前进,否则将很难跟踪正在发生的事情,并且较低的地址与较高的地址一样好。曾经是堆栈和堆相互增长,这将允许使用大量堆栈而不是太多堆的代码在相同数量的内存中工作,就像使用较少堆栈和大量内存的代码一样。堆。但是现在,通常有足够的内存(空间),可以将堆定义为与堆栈完全分离的某个地方。相反,堆栈溢出是通过在堆栈顶部有一个不可用的“保留”内存区域来检测的 - 因此操作系统会获得一个“陷阱”来使用不可用的内存,并且可以杀死应用程序.

于 2013-05-30T14:10:33.160 回答