【问题标题】:Stack and heap memory of a C programC 程序的堆栈和堆内存
【发布时间】:2016-06-19 00:29:31
【问题描述】:

我试图了解 CPU 在跟踪程序堆栈/堆分配中的作用。

阅读一些材料,我遇到了这个:

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

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

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

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

【问题讨论】:

  • 这完全取决于实现。在传统的 Unix 系统中,堆会从静态内存的末尾向下增长,而堆栈将从地址空间的底部向上增长。但是 C 规范中没有任何内容。这需要这个,而现代多线程实现并不那么简单。
  • 如果你想在你的系统上测试这个,试着做一些测试: 编写一个打印全局初始化变量地址的程序,一个全局未初始化变量,一些存储返回由malloc 和自动(堆栈)变量的地址。看看它们如何适应地址空间。

标签: c memory memory-management


【解决方案1】:

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

基于堆栈架构的 CPU(代表当今使用的绝大多数 CPU)具有用于堆栈指针的特殊寄存器。这是可能的,因为堆栈就其本质而言不会碎片化。因此,单个指针就足够了。

没有“堆指针”之类的东西,因为堆可能是一个碎片化的数据结构。堆分配器保持一个特殊的内存碎片表可供分配,并在程序分配和释放内存时对其进行调整。内存管理器还保存一个指向已从堆中分配的最高地址的指针。

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

由于栈指针不能越过不报错,很多系统都将栈的大小限制在一定的范围内,并保证内存分配器不会让堆的高点越过栈的上限.

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

【讨论】:

  • 堆分配器驻留在哪里?由于它正在处理程序堆,它是程序虚拟地址空间的一部分,我假设它与虚拟内存管理器是分开的?
  • @wulfgarpro 在具有虚拟内存堆分配器的系统上,通常位于虚拟内存管理器的顶部,从中获取大块,并将它们分配给单独的堆内存请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 2017-01-04
  • 1970-01-01
  • 2012-09-06
  • 2020-10-10
  • 2011-10-21
相关资源
最近更新 更多