为何C语言运行提示double free or corruption (out) Aborted错误
错误根因
你的代码触发double free or corruption(out)报错的核心问题是内存申请与释放的逻辑完全不匹配:
- 构建链表时你只调用了一次
malloc(4 * sizeof(node)),一次性申请了能存4个node的连续堆内存块,n是这块内存的唯一合法起始地址,4个节点都是这块连续内存里的元素,不是独立分配的堆块。 - 释放内存时你沿着链表逐节点调用
free():第一次执行free(list)时,因为list指向n[0]也就是这块内存的起始地址,已经把整个4节点占的整块堆内存完全交还给操作系统了。后续你再对同一块内存内部的n[1]、n[2]、n[3]地址调用free(),属于对非malloc返回的地址做释放、对已释放内存重复操作,直接触发堆内存校验机制中止程序。 - 你的遍历打印逻辑本身没有指针指向错误,所以打印环节能正常输出1、2、3、4,报错只会出现在释放阶段。
修复方案
二选一即可:
方案1:匹配现有一次性分配内存的写法
既然是一次申请的连续内存,不需要逐节点释放,只需要释放一次malloc返回的原始地址即可,删掉原来的逐节点释放while循环,替换为:
free(n); n = NULL; list = NULL;
方案2:实现常规独立节点单链表的逐节点释放逻辑
如果要保留逐节点释放的写法,就不要一次性申请4个节点的内存,改为每个节点单独调用malloc分配,这样每个节点的地址都是malloc直接返回的合法地址,逐节点释放就不会出错,参考实现:
int main(void) { node *list = NULL; // 逐节点分配内存构建链表 for (int val = 1; val <= 4; val++) { node *new_node = malloc(sizeof(node)); if (new_node == NULL) { return 1; } new_node->number = val; new_node->next = NULL; // 追加到链表尾部 if (list == NULL) { list = new_node; } else { node *cur = list; while (cur->next != NULL) { cur = cur->next; } cur->next = new_node; } } // 遍历打印逻辑和原代码一致 for (node *tmp = list; tmp != NULL; tmp = tmp->next) { printf("%i\n", tmp->number); } // 逐节点释放合法 while (list != NULL) { node *tmp = list->next; free(list); list = tmp; } return 0; }
内存释放核心规则:传给
free()的指针必须是malloc/calloc/realloc直接返回的原始起始地址,不能传入同一块堆内存内部的偏移地址,也不能对同一块堆内存重复调用free()。
内容的提问来源于stack exchange,提问作者Grgi
相关产品推荐
相关产品推荐

