C语言realloc内存重分配异常致程序终止问题求助
解决realloc导致程序终止的问题
核心错误分析
输入处理与内存越界
- 输入
size后,scanf会在缓冲区留下换行符,后续fgets会优先读取这个空行,导致输入验证逻辑混乱。你用while(fgets(...))循环读取到EOF的逻辑,会让buffer仅保留最后一次读取内容,且输入的数字串没有终止符,strcpy(list, buffer)会因找不到'\0'越界,破坏堆内存结构,为后续realloc崩溃埋下隐患。 - 初始
malloc仅分配size*sizeof(char)内存,但strcpy需要目标内存容纳字符串终止符,应分配size+1字节。
- 输入
realloc内存计算错误
size++后,新内存大小应为(size+1)*sizeof(char)(预留终止符空间),原代码写成size+1,结合之前的堆破坏问题,直接触发程序终止。元素存储类型不匹配
原有列表存储数字字符(如'1'对应ASCII 49),但添加元素时直接将int类型的tempElem(如输入3得到值3)存入数组,实际存储的是ASCII值3(不可见字符),导致排序和打印逻辑完全错误,应转换为对应字符:list[size-1] = tempElem + '0';循环退出条件错误
主循环while(input != 0)不符合需求,应改为while(input != 2),否则输入2无法退出程序。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> void insert(int size, char *arr); void swap(char *arr, int pos1, int pos2); void printList(int size, char *arr); int main() { int size = 0; do { printf("Put in size of the list (Range[1;2^16-1]): "); scanf(" %d", &size); if (size <= 0) printf("Put in a correct length!\n"); } while (size <= 0); // 清除scanf遗留的换行符 getchar(); printf("Put in ur List: "); char buffer[size + 2]; // 预留换行符和终止符空间 int errFlag; do { errFlag = 1; // 仅读取一行输入 if (!fgets(buffer, sizeof(buffer), stdin)) { errFlag = 0; break; } // 去掉换行符并添加终止符 buffer[strcspn(buffer, "\n")] = '\0'; // 验证输入长度是否符合要求 if (strlen(buffer) != size) errFlag = 0; // 验证输入是否全为数字 for (int i = 0; i < size; i++) if (!isdigit(buffer[i])) errFlag = 0; if (errFlag == 0) printf("Input failed try again: "); } while (errFlag == 0); // 分配包含终止符的内存 char *list = malloc((size + 1) * sizeof(char)); if (!list) { perror("malloc failed"); return 1; } strcpy(list, buffer); insert(size, list); printList(size, list); int input = 0; do { printf("\nDo u want to add another element(1) or a list(0)? If u want to stop type (2): "); scanf(" %d", &input); if (input != 0 && input != 1 && input != 2) printf("\nInput failed try again: "); else if (input == 1) { int tempElem = 0; printf("Input ur element: "); scanf(" %d", &tempElem); // 验证输入为单个数字 if (tempElem < 0 || tempElem > 9) { printf("Please input a single digit!\n"); continue; } size++; // 用临时指针接收realloc结果,避免内存泄漏 char *temp_list = realloc(list, (size + 1) * sizeof(char)); if (!temp_list) { perror("realloc failed"); free(list); return 1; } list = temp_list; // 将int转为对应字符存储 list[size - 1] = tempElem + '0'; list[size] = '\0'; // 确保字符串终止符 printf("New "); insert(size, list); printList(size, list); } } while (input != 2); // 输入2退出程序 free(list); // 释放动态内存 return 0; } void insert(int size, char *arr) { for (int i = 1; i < size; i++) { int j = i - 1; while (j >= 0 && arr[j] > arr[j + 1]) { swap(arr, j, j + 1); j--; } } } void swap(char *arr, int pos1, int pos2) { char temp = arr[pos1]; arr[pos1] = arr[pos2]; arr[pos2] = temp; } void printList(int size, char *arr) { printf("ArrayList: "); for (int i = 0; i < size; i++) { printf("[%d] ", arr[i] - '0'); } }
修正说明
- 处理
scanf遗留的换行符,避免fgets读取空行。 - 优化输入读取逻辑,只读取一行并验证长度和字符合法性。
- 内存分配时预留字符串终止符空间,彻底解决越界问题。
- 用临时指针接收
realloc结果,避免分配失败时丢失原内存地址。 - 统一存储格式,将新增数字转为对应字符。
- 修正循环退出条件,符合需求逻辑。
- 程序结束前释放动态内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Mystical Baum
相关产品推荐
相关产品推荐

