1

进程的虚拟地址空间以进程的textdatabss段开始。放置此堆分配后,堆会向更大的内存地址增长。但是,在使用堆的一部分之前,必须分配内存块(valloc等等),否则segfault会发生(或应该发生)。

堆栈从虚拟地址空间中的初始大地址向更小的值增长。据我所知,这无需虚拟内存分配即可工作。如果在堆的情况下这是不可能的,如何在没有事先分配内存的情况下使用堆栈?(它是相同的线性虚拟地址空间。)

据 ai 所知alloca,它的实现方式与sub esp, <size>. 但是堆栈使用的虚拟地址空间区域必须在此之前以某种方式分配,对吗?

4

1 回答 1

1

在某种程度上,它确实存在段错误。这是一种“惰性”优化。操作系统尽可能多地作弊,只要差异不可从外部观察到。

但是,陷阱不会像正常的段错误那样导致生成信号(默认情况下会终止进程)。相反,操作系统会验​​证允许的线程大小尚未超过,然后从零池中拉出一个新页面。

在 Windows 下,该机制被称为“保护页面”,我不知道在 Linux 下有类似的命名。无论哪种方式,从技术上讲,保护页面只不过是一个写保护页面(或不存在的页面),操作系统将其记住为“特殊”,因此当它被触摸时可能会发生一些特定的动作。

malloc这也与动态分配(调用sbrk)的工作方式非常相似。当您分配内存时,只要您不访问分配的内存,就不会发生太多事情。唯一发生的事情是操作系统“记住”您增加了数据段。
如果现在发生故障,操作系统将创建页面,或者分别从零池中拉取它,并假装它一直在那里。你永远不知道它以前不存在。

于 2012-07-23T14:55:26.520 回答