2016-06-19 297 views
3

我想了解CPU在跟踪程序堆栈/堆分配中的作用。C程序的堆栈和堆内存

阅读一些材料,我遇到这样的:

堆栈区域传统上邻接堆区域和增长的相反方向;当堆栈指针遇到堆指针时,空闲内存耗尽。

堆栈和堆指针是否存储在程序特定的寄存器中?

如果堆栈指针指向栈顶,并且(我假设)堆栈指针指向堆栈的末尾,这些指针在不覆盖内存(溢出)的情况​​下会如何满足?

这在现代系统中如何工作?

+0

这是所有实现相关的。在传统的Unix系统中,堆将从静态存储器的末端开始下降,并且堆栈将从地址空间的底部开始增长。但是C规范中没有任何内容。这需要这一点,并且与现代多线程实现相比,事情并不那么简单。 –

+0

如果你想在*你的系统上测试这个,试着做一些测试:编写一个程序,打印全局初始化变量的地址,全局未初始化变量,'malloc'返回的一些存储以及一个自动堆栈)变量。看看它们如何适应地址空间。 –

回答

3

堆栈和堆指针是否存储在特定于程序的寄存器中?

基于堆栈的体系结构(代表当前使用的绝大多数CPU)的CPU有一个特殊的堆栈指针寄存器。这是可能的,因为堆栈本质上不会被分割。因此,一个单一的指针就足够了。

没有“堆指针”这样的事情,因为堆可能是一个零碎的数据结构。堆分配器保留一个特殊的内存片段表供分配,并在程序分配和释放内存时进行调整。内存管理器还保存一个指向从堆中分配的最高地址的指针。

如果堆栈指针指向堆栈的顶部,和(我假设)堆指针指向堆的结束,怎么会这些指针永远满足,而不会覆盖内存(溢) ?

由于堆栈指针不能不会导致错误交叉,许多系统限制堆到一定数量的大小,并确保内存分配器不会让堆的高点越过上限的堆栈。

注意:在支持并发的系统上,一次可能有多个活动的堆栈。在这种情况下,堆栈被设置为彼此相邻,并监视上限以检测堆栈溢出。这里是an article that describes techniques for detecting stack overflows

+0

堆分配器驻留在哪里?由于它涉及程序堆,它是程序虚拟地址空间的一部分,我假设它是与虚拟内存管理器分开的东西? – wulfgarpro

+0

@wulfgarpro在具有虚拟内存堆分配器的系统上,通常位于虚拟内存管理器的顶部,从中获取大块,并将它们分配给各个堆内存请求。 – dasblinkenlight