此文章用于详细介绍malloc_consolidate。
众所周知,fastbin一般是不能合并,但在malloc_consolidate中是个例外。
1.触发机制
首先构造这样的堆块结构
一个0x40的堆块在fastbin中,一个0x110的堆块在unbin中
随后我们尝试分配一个0x300的堆块。
可以看到0x110的usbin被丢到了smallbin中,fastbin没有被合并
但我们试着改成分配0x500的堆块。
可以看到fastbin和usbin完成了合并,并被放到了smallbin中。
得出结论:当你malloc一个大于smallbin的堆块,它会将fastbin拿到usbin中,让它尝试与周围的堆块合并,如果没被分配,就扔到适当的bin中。
这里可能有人会有疑惑:如果fastbin不能合并,是否还会被分配到smallbin中?fastbin之间在这种情况下能否合并?
开始试验:
这次我们只free一个fastbin,然后再尝试malloc(0x500),以下是结果。
可以看到,即使fastbin不参与合并,也会被先被拉进usbin,然后被扔到smallbin中。
接下来进行第二个实验:
我们先释放了2个fastbin,然后再尝试malloc(0x500),以下是结果:
即使是fastbin之间,也会进行合并!
2.补充
之前一直以为fastbin自身的pre_inuse一直是1,所以一直在想合并的时候fastbin怎么识别前面的chunk是不是freechunk。
但经过试验发现,当前面的chunk是freechunk并且不是fastbin的时候,自身的pre_inuse为0,只是不参与合并。
当一个chunk被free时,若它属于fastbin,则它的下一个chunk的pre_inuse位不会被改变。