C程序意外终止且无法释放sortOrder变量技术求助
问题分析与修复方案
首先看你遇到的两个核心问题:程序随机崩溃、main中释放内存时报错,根源都在内存缓冲区溢出和内存分配的不严谨上,咱们一步步拆解:
1. 缓冲区溢出(导致随机崩溃的元凶)
在statusOfFiles函数里,你给每个sortOrder[i]分配内存时只算了文件名的长度加1:
(*sortOrder)[i] = (char*)malloc((strlen(file) + ZERO_END) * sizeof(char));
但紧接着你执行了strcat(strcpy((*sortOrder)[i], file), " - "),之后还会在addResults里追加更长的状态字符串(比如"Infected! (first 20%)"),这直接超出了分配的内存大小,会破坏堆内存结构——这就是程序随机崩溃、释放内存时报错的核心原因。
2. 内存分配的不严谨问题
main里初始化sortOrder用了malloc(0),这是未定义行为(不同编译器处理方式不同),应该初始化为NULL,因为realloc(NULL, size)等价于malloc(size),更安全。- 所有
malloc和realloc都没有检查返回值,如果内存分配失败,后续操作会直接崩溃。
修复后的完整代码
下面是修复好的代码,我标注了关键修改点:
#define _CRT_SECURE_NO_WARNINGS #include <errno.h> #include <stdio.h> #include <string.h> #include <dirent.h> #include <stdlib.h> #include <sys/stat.h> #define ADD_NAME 1 #define MAX_LEN 200 #define ZERO_END 1 #define VIRUS 2 #define CLEAN 0 #define INFECTED 1 #define FIRST_PART 2 #define LAST_PART 3 // 计算最长状态字符串的长度,避免缓冲区溢出 #define MAX_STATUS_LEN 30 // 足够容纳最长的状态文本:"Infected! (first 20%%)" void addResults(int foundDetails, char*** sortOrder, int i) { if (foundDetails == CLEAN) { strcat((*sortOrder)[i], "Clean"); } else if (foundDetails == INFECTED) { strcat((*sortOrder)[i], "Infected!"); } else if (foundDetails == FIRST_PART) { strcat((*sortOrder)[i], "Infected! (first 20%)"); } else { strcat((*sortOrder)[i], "Infected! (last 20%)"); } } void statusOfFiles(char * filePath, char ** files, int lenFiles, char*** sortOrder) { char file[MAX_LEN] = { 0 }; int i = 0; for (i = 0; i < lenFiles; i++) { strcpy(file, filePath); strcat(file, "/"); strcat(file, files[i]); // 1. 重新分配数组内存,检查返回值 char** temp = (char**)realloc((*sortOrder), (i + ADD_NAME) * sizeof(char*)); if (!temp) { perror("realloc failed"); // 内存分配失败时,先释放已分配的内存避免泄漏 for (int j = 0; j < i; j++) { free((*sortOrder)[j]); } free(*sortOrder); *sortOrder = NULL; return; } *sortOrder = temp; // 2. 计算所需总内存:文件名长度 + " - "的长度 + 最长状态长度 + 结束符 size_t totalSize = strlen(file) + 3 + MAX_STATUS_LEN + ZERO_END; (*sortOrder)[i] = (char*)malloc(totalSize * sizeof(char)); if (!(*sortOrder)[i]) { perror("malloc failed"); // 清理已分配资源 for (int j = 0; j < i; j++) { free((*sortOrder)[j]); } free(*sortOrder); *sortOrder = NULL; return; } // 3. 安全拼接字符串 strcpy((*sortOrder)[i], file); strcat((*sortOrder)[i], " - "); addResults(0, sortOrder, i); } } void printResultsInOrder(char** sortOrder, int len) { int i = 0; for (i = 0; i < len; i++) { printf("%s\n", sortOrder[i]); } } int main(void) { int i = 0, len = 5; char *fileNames[] = {"adgv.txt", "fsagda", "adagda", "adga", "adgastgaet"}; // 初始化为NULL,代替malloc(0) char** sortOrder = NULL; statusOfFiles("C:/folder", fileNames, len, &sortOrder); // 检查sortOrder是否有效,避免空指针访问 if (sortOrder) { printResultsInOrder(sortOrder, len); // 释放每个字符串 for (i = 0; i < len; i++) { free(sortOrder[i]); } free(sortOrder); } getchar(); return 0; }
关键修改说明
- 解决缓冲区溢出:提前计算好文件名、分隔符、最长状态字符串的总长度,一次性分配足够的内存。
- 安全的内存分配:每次
realloc和malloc后都检查返回值,分配失败时清理已分配的内存,避免内存泄漏。 - 初始化优化:把
sortOrder初始化为NULL,避免malloc(0)的未定义行为。 - 空指针检查:在
main里先确认sortOrder有效再执行打印和释放,避免崩溃。
内容的提问来源于stack exchange,提问作者Gderu
相关产品推荐
相关产品推荐

