栈能长成堆吗?

Can the stack grow into the heap?

我目前正在学习操作系统,我了解到堆栈位于内核和堆之间。令我困惑的是,在大多数实现中,由于堆栈趋于向下增长,而堆增长到更高的内存地址,是什么阻止了堆栈增长到堆中?如果有可能,如果它真的长到堆中会发生什么?

这不一定正确:

I'm currently learning about operating systems and I learned that the stack is located between the kernel and the heap.

栈和堆只是内存。除了它们的使用方式外,它们是无法区分的。地址space.

可以有多个堆和多个栈

堆无法增长到堆栈中,反之亦然。操作系统不允许堆重新分配已分配给堆栈的内存。

可以访问堆栈末尾之外的内存,理论上,这可能是堆的一部分。一些操作系统将不可访问的守卫放在堆栈的末尾。

内存的简化视图传统上看起来像这样:

 ===================
| Operating System  | High memory
 ===================
|   Your program    |
|  ---------------  |
| | Process stack | |
|  ---------------  | Transient program area
| |  Process heap | |
|  ---------------  |
| |  Program code | |
|  ---------------  |
 ===================
| Operating system  | Low memory
 ===================

正如您所指出的,进程堆栈从操作系统代码的正下方开始,并向下增长。另一方面,进程堆从固定程序代码上方开始,并向上增长。

在早期的 PC 操作系统中,这实际上是程序在内存中的物理布局。例如CP/M操作系统,为某些操作系统bootstrap代码预留了前256字节的内存,其余必要的操作系统服务占用了高端内存区。程序从地址 0x0100 开始,可以使用从那里到顶部操作系统代码开始之间的所有内存。 MS-DOS 非常相似。

没有任何防护措施可以防止您提到的事情发生:程序会在堆栈上分配如此多 space 以致于它覆盖了在堆上分配的内存。或者,程序会分配覆盖处理器堆栈的堆内存。当其中任何一种情况发生时,程序就会崩溃。在某些情况下,操作系统也会崩溃。当然,因为一次只能有一个程序 运行,所以这没什么大不了的:只需重新启动机器并重试。

现代计算机具有更高级的内存布局,并且该概念图不再适用。今天的操作系统可以更好地执行内存访问限制。例如,一个进程为其堆栈分配了一个固定段(通常为 1 兆字节的数量级)。如果程序试图使用比分配的更多的堆栈space,内存管理器将不允许它。该程序将因访问冲突而崩溃。同样的道理,程序的堆不能增长到分配给栈的内存中。