C语言程序触发double free错误致SIGABRT终止,请求排查修复
修复C语言中的Double Free内存错误
我来帮你排查这个导致程序触发SIGABRT的内存问题,你遇到的free(): double free detected in tcache 2是典型的重复释放内存错误,咱们一步步拆解问题:
直接触发错误的原因:重复释放l_sub_seq
看你代码最后这段释放内存的逻辑:
for(int i = 0; i < n; i++) free(l_sub_seq);
l_sub_seq是通过calloc(n, sizeof(int))一次性分配的单块连续内存,只需要调用一次free(l_sub_seq)就能正确释放。但你循环了n次去释放同一个指针——第一次释放后,这块内存已经归还给系统,后续再对同一个指针执行free操作,就会触发double free,直接导致程序收到SIGABRT信号终止。
隐藏的内存风险:seqList元素未初始化
另外还有个容易被忽略的问题:seqList是用malloc分配的指针数组,而malloc不会初始化内存,所以数组里的每个int*都是随机的垃圾值。当第一次对某个seqList[i]调用realloc时,你其实是在对一个野指针进行操作,这属于未定义行为,可能会导致内存损坏或者其他奇怪的崩溃。正确的做法是把seqList的每个元素初始化为NULL,因为realloc(NULL, size)的效果等同于malloc(size),是完全安全的。
额外的小问题:输出语句错误
原代码中case2的printf(" ");是无效的,应该改为printf("%d\n", lastAnswer);,否则不会输出查询到的结果,这个我也顺便帮你修正了。
修复后的完整代码
#include<stdio.h> #include<stdlib.h> int main(void) { int **seqList, n, q; scanf("%d %d", &n, &q); seqList = (int**)malloc(n * sizeof(int*)); // 初始化seqList的每个元素为NULL,避免野指针风险 for(int i = 0; i < n; i++){ seqList[i] = NULL; } int *l_sub_seq = (int*)calloc(n, sizeof(int));//子序列长度数组 int lastAnswer = 0; while(q--) { int type, x, y, i; scanf("%d %d %d", &type, &x, &y); i = (x^lastAnswer) % n; switch(type) { case 1: l_sub_seq[i]++; seqList[i] = (int*)realloc(seqList[i], sizeof(int)*l_sub_seq[i]); seqList[i][l_sub_seq[i] - 1] = y; break; case 2: lastAnswer = seqList[i][y%l_sub_seq[i]]; printf("%d\n", lastAnswer); break; } } // 释放每个子序列的内存 for(int i = 0; i < n; i++) { free(seqList[i]); } free(seqList); // 只释放一次l_sub_seq free(l_sub_seq); return 0; }
内容的提问来源于stack exchange,提问作者Gulshan Mishra
相关产品推荐
相关产品推荐

