简介:围绕 C 语言动态内存分配机制的手写 malloc 实践资源,面向希望从调用库函数进阶到理解内存管理内部运作的开发者,可作为操作系统、C 语言进阶与数据结构课程的配套练习。压缩包共 3 个文件,含 2 个 .c 源文件与 1 个 .h 头文件,整体约 3KB;头文件提供接口声明,源文件承载分配器实现与测试用例,体量轻巧,便于编译调试和逐行阅读。已有 1830 人学习,反映该主题在内存管理入门与面试复习中具有稳定关注度。内容以 my_malloc 为主线,涉及堆区划分、内存块组织、空闲块查找与拆分、释放时相邻块合并,以及空闲内存不足时扩展内存池等环节;也提示对齐约束、多线程并发控制和首次适配、最佳适配、最差适配等策略对碎片与性能的影响。读者可据此搭建最小分配器原型,观察分配与释放过程,形成排查内存泄漏、评估碎片和优化分配策略的实践认知。
1. 从一次堆越界排查说起:为什么我决定自己写一个 malloc
去年排查一个长跑进程内存缓慢上涨的问题,我在调试器里对着堆布局看了整整一个下午,最后定位到某段代码把 24 字节的请求写到了 32 字节之外——越界的那几个字节正好压在相邻 chunk 的头部上,程序当时一点事没有,直到后面某次 free 才炸出来。那次之后,我把 malloc 当黑匣子的习惯改了。
这份资源做的事很直接:不调用通用 C 库的分配器,自己用 sbrk 从内核拿堆,自己维护 chunk 头和空闲链表,把 malloc、free、realloc、calloc 四个函数从零写一遍,再配一套能跑起来的验证用例。它适合两类人:想搞清楚指针背后到底发生了什么的初学者,以及被内存问题折腾过、想补上这块底层认知的业务开发。它不追求性能超越成熟实现,追求的是每一行都能自己讲清楚。
2. 分配器骨架:chunk 结构、堆边界与空闲链表怎么摆
写分配器要先回答三个问题:内存从哪来、怎么记住每块多大、怎么找回已经释放的块。这三件事对应三个数据结构——堆边界、chunk 头部、空闲链表。骨架搭对了,后面的 malloc/free 只是在这套结构上做加减法;骨架搭歪了,后面每加一个功能都是在给未来埋雷。
2.1 chunk 头部:16 字节里塞下大小和三个标志位
对外接口和标准库保持同名同签名,这样现有代码把malloc换成mini_malloc就能直接编译:
/* mini_malloc.h —— 对外只暴露四个函数,签名与标准库保持一致 */ #ifndef MINI_MALLOC_H #define MINI_MALLOC_H #include <stddef.h> void *mini_malloc(size_t n); void mini_free(void *p); void *mini_realloc(void *p, size_t n); void *mini_calloc(size_t nmemb, size_t size); #endif每个内存块前面挂一个 16 字节的头,结构只有两个size_t:
/* chunk 头部: <p> <a href="https://download.csdn.net/download/asialiyazhou/8539537" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>