第二次调用realloc失败求助:动态扩容数组触发SIGABRT
解决realloc二次调用触发SIGABRT的问题
兄弟,我太懂你这种踩坑的感受了——第一次用realloc扩容数组没问题,第二次直接触发SIGABRT崩溃,十有八九是内存管理的细节没处理好,把堆结构搞坏了。结合你说的场景(存待排序单词,初始10元素,每次扩容加10),我给你捋捋最可能的几个坑和对应的解决办法:
最常见的坑:直接用原指针接收realloc返回值
很多人图省事会写:
strings = realloc(strings, new_size);
但如果realloc因为内存不足返回NULL,你原来的指针就直接丢了,而且后续操作NULL指针或者继续往原内存写,直接就把堆搞炸了,第二次调用realloc时系统就会检测到堆损坏,触发SIGABRT。
正确做法:用临时指针先接收返回值,确认成功再替换原指针:
char **temp = realloc(strings, new_capacity * sizeof(char*)); if (temp == NULL) { // 内存分配失败,先把已经分配的资源清理干净再退出 perror("realloc 分配失败"); // 先释放每个单词的内存 for (int i = 0; i < current_count; i++) { free(strings[i]); } free(strings); exit(EXIT_FAILURE); } strings = temp;
第二大坑:容量和已使用数搞混了
你初始数组是10个元素,每次要扩容加10,得严格区分当前容量(capacity)和已使用的元素数(current_count):
- 初始
capacity = 10,current_count = 0 - 当
current_count >= capacity时,才需要扩容:capacity +=10,然后扩容到capacity * sizeof(char*)(注意要乘指针的大小!)
如果不小心把current_count当成新容量,或者漏乘sizeof(char*),分配的内存不够,后续写入就会越界,破坏堆结构,第二次realloc必然崩。
其他可能的小坑
- 未初始化指针数组元素:初始用malloc分配的指针数组里全是随机垃圾值,如果在添加单词前没把未使用的位置置为
NULL,或者释放时误操作了这些垃圾指针,会直接搞坏堆。 - 字符串内存没管好:每个单词如果是用
malloc/strdup分配的,要确保没重复释放、没内存泄漏,不然堆结构被破坏后,realloc这类堆操作肯定出问题。
给你个完整的可参考示例代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int capacity = 10; // 数组当前总容量 int current_count = 0; // 已存入的单词数量 // 初始分配存单词指针的数组 char **strings = malloc(capacity * sizeof(char*)); if (strings == NULL) { perror("初始malloc失败"); exit(EXIT_FAILURE); } // 模拟读取单词(这里从标准输入读,你可以换成自己的读取逻辑) char buffer[100]; while (fgets(buffer, sizeof(buffer), stdin) != NULL) { // 去掉换行符 buffer[strcspn(buffer, "\n")] = '\0'; // 检查是否需要扩容 if (current_count >= capacity) { capacity += 10; char **temp = realloc(strings, capacity * sizeof(char*)); if (temp == NULL) { perror("realloc扩容失败"); // 清理已分配的所有资源 for (int i = 0; i < current_count; i++) { free(strings[i]); } free(strings); exit(EXIT_FAILURE); } strings = temp; printf("已扩容到容量:%d\n", capacity); } // 复制单词到堆内存(用strdup省事儿,本质是malloc+strcpy) strings[current_count] = strdup(buffer); if (strings[current_count] == NULL) { perror("strdup分配单词内存失败"); // 清理资源 for (int i = 0; i < current_count; i++) { free(strings[i]); } free(strings); exit(EXIT_FAILURE); } current_count++; } // 排序(用qsort+strcmp就行) qsort(strings, current_count, sizeof(char*), (int(*)(const void*, const void*))strcmp); // 打印排序结果 printf("排序后的单词:\n"); for (int i = 0; i < current_count; i++) { printf("%s\n", strings[i]); free(strings[i]); // 用完每个单词就释放 } free(strings); // 最后释放指针数组 return 0; }
你可以对照自己的代码,先检查有没有犯上面说的前两个大坑,大概率就能解决问题了。
内容的提问来源于stack exchange,提问作者user25758
相关产品推荐
相关产品推荐

