所以我理解堆栈溢出是什么,当内存冲突时(以及本网站的标题)但我不明白的是为什么堆栈的新条目在递减的内存地址中。为什么它们不在随机存储器地址中,它是否更有意义,因此内存冲突不是问题?我猜这背后有某种优化原因?
**编辑**
我没有意识到堆栈被赋予了x个地址空间。现在有道理,但带我到后续问题。我可以明确说明我想要分配给堆栈的内存量吗?
答案 0 :(得分:3)
“内存冲突”更适合“缓冲区溢出”这一术语,您可以在预定义空间外写入,但可能位于不同的已分配内存块中。
堆栈溢出不是在一个内存分配之外写入另一个内存分配。它只是在一个堆栈内存分配之外写入。很可能在堆栈之外有一个保护存储器页面,它不会被分配给任何东西,并且会导致读取或写入尝试出错。
为堆栈上推送的每个值分配一个随机地址,这使得很难在堆栈上找到数据(并且它不再是堆栈)。当编译器或程序员知道后续元素占用后续地址时,只需从堆栈帧的基指针计算这些地址就很容易。
答案 1 :(得分:1)
这个问题的答案可能很复杂,但基本上堆栈操作被认为是非常原始的函数,处理器将其作为代码正常执行的一部分。 (保存返回地址和其他内容。)
那你在哪里放置内存管理代码?您在哪里跟踪分配的地址或添加代码以分配新地址?实际上没有任何地方可以做到这一点,因为这些是处理器本身执行的基本操作。
与保存代码本身的内存类似,假设在代码运行之前设置堆栈(并由堆栈寄存器指向)。实际上没有任何地方可以将复杂的内存管理添加到堆栈内存中。所以,是的,如果没有提供足够的内存,堆栈将会溢出。
答案 2 :(得分:1)
堆栈溢出是指您用完了所有可用的堆栈空间。在大多数情况下,可用于堆栈的空间只是系统设计者选择的任意限制。可以改变这种情况,但在现代系统上,它并不是一个真正的问题 - 代码需要几兆字节的堆栈,除非系统非常庞大,可能没有正确设计。
堆栈从“自定义”向零增长 - 它必须按照定义的方向进行,否则将很难跟踪正在发生的事情,并且较低的地址与高地址一样好。它曾经是堆栈和堆相互增长,这将允许使用大量堆栈而不是堆的代码在与使用较少堆栈和较大数量的堆栈的内存相同的内存中工作。堆。但是现在,通常有足够的内存(空间)可以将堆定义为完全独立于堆栈的某个位置。相反,通过在堆栈顶部放置一个“保留”内存区域来检测堆栈溢出是不可用的 - 因此操作系统获得了使用不可用内存的“陷阱”,应用程序可能会被杀死。