C语言手动实现malloc出现段错误,Valgrind报Invalid read of size 4如何解决?
问题原因排查和解决
核心错误原因
- 拆分空闲块时,若分配的是链表第一个节点(
prev == NULL),没有更新全局head指针指向拆分后的新空闲节点,导致head仍然指向已经被分配出去的内存块 - 后续你给已分配块的前8字节写入头部信息(大小、魔数),直接覆盖了原空闲节点结构体的
size和flink字段,导致链表遍历的时候读取到非法的flink指针,触发段错误
这个现象和你测试的表现完全吻合:注释掉写头部的两行代码时,已分配块前8字节还保留着原空闲节点的结构体数据,链表遍历可以正常拿到合法的下一个节点指针,就不会触发段错误。Valgrind打印的非法下一个节点地址0x3e7000000028,其中高32位的0x3e7就是你写入的魔数999的十六进制值,也可以佐证这个判断。
修复方案
在拆分块的逻辑中补充prev == NULL时更新全局head的代码即可:
if (current->size - minimum_chunk_size >= 16) { // allocate tail end // set up new freelistnode struct freelistnode * new = (FreeListNode)(ptr + minimum_chunk_size); new->size = current->size - minimum_chunk_size; if (prev != NULL) { prev->flink = new; } else { // 新增这行:如果是链表首节点拆分,更新head指向新的空闲块 head = new; } new->flink = current->flink; }
同时注意你代码中sbrk申请新内存块的分支也存在同样的head更新遗漏问题,建议同步补上对应判断逻辑,避免后续触发同类错误。
内容的提问来源于stack exchange,提问作者Suds
相关产品推荐
相关产品推荐

