常规意义上,我们对 malloc / free 的理解是,我们通过这两个 API 在进程中调用,用来向操作系统申请内存。
那你有没有想过 malloc / free 是如何工作的呢。
前面的章节中我们提到,malloc 申请得到的内存,都会带上 Cookie 用于记录这块内存的边界。为了减少 malloc 带来的 overhead,在 GNU 中提出了使用链表来负责内存分配与回收的方式。那么 malloc / free 又是如何管理内存的呢。
在讲 malloc 之前,有必要先了解一下一个 CPP 程序是如何运行的。
上图左是 VC6 CPP 在运行的时候的调用栈,由下往上看
mainCRTStartup
函数,调用 C Runtime,分配内存,初始化 C 的标准库等main
函数exit
函数,退出和处理相关内容同样,VC10 CPP 的 call stack 也差不多,只不过在 mainCRTStartup
函数中,去掉了部分内容。
这一部分有区别的内容就是 SBH(Small Block Heap)的相关内容。而在 VC10 中,SBH 的相关内容已经由 windows 操作系统API HeapAlloc
提供了,所以后续就移除掉了。见上图右。
见上图左,标记1处。在进入 mainCRTStartup
之后,会首先调用 _heap_init
函数,CRT会先为自己建立一个 _crtheap
(一开始申请的 heap 大小是 4096 bytes,刚好是一个内存页的大小),然后再调用 _sbh_heap_init
函数,从中配置 SBH 所需的 headers(大小是16)。
下图就反馈了以上两个函数的细节。