fast bins 的大小范围
- 单个 fast bin 管理的块大小
每个 fast bin 对应一种固定大小的内存块,块大小按 8 字节递增(32 位系统)或 16 字节递增(64 位系统)。
64 位系统示例(常见场景):
最小块大小:
0x20字节(包含 16 字节的头部0x10+ 对齐填充0x10)。最大块大小:
0x80字节(即fastbin_max_size = 0x80,超过此大小的块不属于 fast bins)。有效大小序列:
0x20,0x30,0x40,0x50,0x60,0x70,0x80(共 7 个 fast bin)。32 位系统示例:
最小块大小:
0x10字节(头部0x8+ 对齐填充0x8)。最大块大小:
0x78字节(fastbin_max_size = 0x78)。有效大小序列:
0x10,0x18,0x20, …,0x78(按 8 字节递增)。
- 关键参数
fastbin_max_size:定义 fast bins 能管理的最大块大小(64 位系统默认0x80,32 位系统默认0x78)。- 块大小计算:块大小需包含头部(
prev_size和size字段)和用户数据区,且需按 16 字节对齐(64 位)或 8 字节对齐(32 位)。
问题 1:Fastbins 的 fd 指向谁?
Fastbins 采用 LIFO(后进先出) 结构,后释放的堆块会放在链表头部,而 **fd** 指向的是先前被释放的堆块。
示例:
1 | ptr1 = malloc(0x10); |
此时堆结构如下:
[ ptr1 ] [ ptr2 ] [ ptr3 ]
释放顺序:
如果我们按照 free(ptr1) -> free(ptr2) -> free(ptr3) 释放堆块,则 Fastbins 的链表结构如下:
Fastbins 结构(LIFO,头部插入):
1 | +---------+ +---------+ +---------+ |
对应的 fd 指针:
1 | ptr3->fd = ptr2 |
Fastbins 结构更新:
1 | +---------+ +---------+ |
再申请一个 malloc(0x10),ptr2 会被分配:
1 | +---------+ |
再申请一个 malloc(0x10),ptr1 被分配,Fastbins 变为空。
完整示意图
释放过程:
1 | free(ptr1) free(ptr2) free(ptr3) |
Fastbins 变成:
ptr3 -> ptr2 -> ptr1 -> NULL
分配过程:
如果 malloc(0x10):
1 | 分配 ptr3: |
再 malloc(0x10):
1 | 分配 ptr2: |
再 malloc(0x10):
1 | 分配 ptr1: |
总结:
- Fastbins 释放时,后释放的堆块会放在链表头部,而
**fd**指向的是先前释放的堆块。 - Fastbins 申请时,总是优先分配最近释放的堆块(LIFO 规则)