链表实现内存分配的核心是用节点模拟空闲/已分配块并以指针串联离散区域;每个节点需记录size、is_free和next,alloc时查找首个足够且空闲的块并可能分割,free时置空闲标志并合并相邻空闲块,defragment通过调整指针聚拢空闲空间。

链表实现内存分配,核心在于用节点模拟“空闲块”和“已分配块”,靠指针串联起离散的内存区域。它不依赖连续地址,而是通过结构体记录每块内存的大小、状态和位置,再用链表组织管理——这才是理解变量空间如何被动态掌控的关键。
节点设计:每个块都要自报家门
一个内存块节点至少得说清三件事:有多大(size)、当前有没有被占用(is_free)、下一块在哪(next)。常见定义像这样:
struct mem_block {
int size;
bool is_free;
struct mem_block* next;
};
注意:节点本身也占内存,通常放在内存池头部或单独管理;真实可用空间从节点之后开始算。
alloc 操作:找一块够大又靠前的空地
分配时不是随便挑,而是遍历链表,找第一个 is_free == true 且 size ≥ 请求大小 的节点。找到后做两件事:
- 如果剩余空间足够大(比如请求10字节,当前块有30字节),就把它“切开”:把原节点 size 改为10,再新建一个节点描述剩下的20字节,连到后面;
- 把该节点的 is_free 设为 false,返回其数据区起始地址(即 (char*)node + sizeof(mem_block));
- 如果没找到合适块,就返回 NULL,并提示“内存不足”。
free 与 defragment:释放不是扔掉,整理不是重排
释放操作不是清空内容,而是把对应节点的 is_free 改回 true,并尝试跟前后空闲块合并(避免碎片化):
- 检查前一个节点是否存在且空闲,是则合并;
- 检查后一个节点是否空闲,是则把它的 size 加到当前块,并跳过它;
- defragment 不是打乱重排,而是把所有空闲块“往前挪”,让已分配块保持原有顺序,空闲空间聚到末尾——这步本质是重建链表,只调整指针,不动数据。
为什么非得用链表?数组不行吗
数组要求连续索引,但内存块的位置是分散的、大小不一的、生命周期不同的。用数组硬套,要么浪费大量索引空间存“空位”,要么每次插入删除都要搬动大量节点。而链表天然适配这种动态、异构、按需连接的场景——增删只改指针,遍历按需跳转,逻辑清晰,扩展自然。










