You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:58:47