这次我们深入了解malloc,malloc究竟分配多么大的空间,以及整个过程是如何进行的。
malloc其实并没有想象中那么低效,在底层的设计中也是充满着精妙之处的。
以下分解内容以VC6版本为基础。
main()的准备工作
下图展示了调用main之前编译器都做了什么。
按照从下往上的顺序,依次调用了1-7这些初始化程序准备函数。
在其中,又会有一些嵌套式的调用。我们可以看到在ioinit中调用了诸如malloc_dbg(),堆分配相关的初始化,以及非常重要的sbh相关函数。
SBH小区块管理
从heap_alloc_base()这段代码中就可以看出,在申请空间小于1016时会调用_sbh_alloc_block(),而其他空间大小则会直接使用系统的HeapAlloc
这里的sbh代表Small Block Heap,是对于申请堆区小空间的管理方式。
而这部分内容在VC10时,这些管理方式被包装到了OS里面。
SBH就是我们要分析的重点。
SBH之始
在开始时,系统会先建立一个_crtheap,初值为4096。
然后调用_sbh_heap_init(),分配配置SBH所需的管理空间。
可以看到这里分配了16个HEADER,类似链表的结构。
而之后动态配置中申请的空间就要与1016比较了,小于就从SBH取,大于就调用HeapAlloc()从_crtheap取
Header的结构如下:
其中Hi和Lo共有64位。Commit有32位。
还有一个指针以及一个结构体指针,这些在后面都会用到。
malloc()的真相
ioinit()申请空间
接下来就会进行一系列的内存分配与管理了。
首先调用的是ioinit(),这里会申请一些信息文件,大小为32*8=256 也就是16进制的100h
然后进入到debug模式