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

C语言中使用malloc动态分配结构体数组的技术求助

用malloc实现结构体数组存储文件信息的解决方案

没问题,我来帮你把这段代码改成用malloc动态分配结构体数组的版本,顺便还会修正原代码里的几个小问题(比如未初始化的文件大小、资源泄漏等)~

首先,先明确几个关键点:原代码里使用的是变长数组(VLA)来存储文件信息,换成malloc的核心就是把静态数组替换为动态分配的内存块,同时要注意内存的申请、检查和释放。

完整修改后的代码

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>

// 定义你的文件信息结构体(原代码里缺失,必须补充)
struct fileStruct {
    char filename[256]; // 预留足够长度存储文件名,兼容大多数系统
    off_t filesize;     // 用off_t类型存储文件大小,适配32/64位系统
};

int getNumberOfFiles(char *path) {
    int totalfiles = 0;
    DIR *d = opendir(path);
    if (!d) { // 检查目录是否成功打开,避免空指针访问
        perror("opendir failed");
        return -1;
    }
    struct dirent *dir;
    while ((dir = readdir(d)) != NULL) {
        // 可选:如果想跳过当前目录"."和上级目录"..",取消下面的注释
        // if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) continue;
        totalfiles++;
    }
    closedir(d); // 原代码遗漏了关闭目录流,会导致资源泄漏,现在补上
    return totalfiles;
}

int main() {
    char *targetPath = ".";
    int totalfiles = getNumberOfFiles(targetPath);
    if (totalfiles <= 0) {
        printf("未找到文件或读取目录失败\n");
        return 1;
    }

    // 核心:用malloc动态分配结构体数组
    // 计算所需总内存:元素个数 × 单个结构体的大小
    struct fileStruct *fileobjarray = malloc(totalfiles * sizeof(struct fileStruct));
    if (!fileobjarray) { // 必须检查malloc是否成功,避免空指针操作
        perror("malloc failed");
        return 1;
    }

    DIR *d = opendir(targetPath);
    if (!d) {
        perror("opendir failed");
        free(fileobjarray); // 即使打开目录失败,也要先释放已分配的内存
        return 1;
    }

    struct dirent *dir;
    struct stat fileStat;
    int i = 0;
    while ((dir = readdir(d)) != NULL) {
        // 可选:和上面getNumberOfFiles里的逻辑保持一致,跳过.和..
        // if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) continue;

        // 拼接完整文件路径,因为stat需要完整路径才能正确获取文件信息
        char fullPath[512];
        snprintf(fullPath, sizeof(fullPath), "%s/%s", targetPath, dir->d_name);
        if (stat(fullPath, &fileStat) == 0) {
            fileobjarray[i].filesize = fileStat.st_size;
        } else {
            fileobjarray[i].filesize = -1; // 获取失败时标记为-1
            perror("stat failed");
        }

        // 安全复制文件名:用strncpy代替strcpy,避免缓冲区溢出
        strncpy(fileobjarray[i].filename, dir->d_name, sizeof(fileobjarray[i].filename) - 1);
        fileobjarray[i].filename[sizeof(fileobjarray[i].filename) - 1] = '\0'; // 确保字符串以'\0'结尾

        i++;
    }
    closedir(d);

    // 可选:打印测试结果,验证数据是否正确
    printf("总计文件数:%d\n", totalfiles);
    for (int j = 0; j < totalfiles; j++) {
        printf("文件名:%s,大小:%lld 字节\n", 
               fileobjarray[j].filename, 
               (long long)fileobjarray[j].filesize);
    }

    // 关键:使用完动态内存后必须释放,避免内存泄漏
    free(fileobjarray);
    return 0;
}

关键修改说明

  • 动态内存分配:用malloc(totalfiles * sizeof(struct fileStruct))申请内存,返回的指针和静态数组用法一致,但内存是在堆上分配的,不会局限于栈的大小限制。
  • 错误检查:对malloc、opendir、stat的返回值都做了检查,避免程序崩溃或出现未知错误,比如malloc失败时会打印错误信息并退出。
  • 资源与内存释放:添加了closedir(d)关闭目录流,以及free(fileobjarray)释放动态内存,彻底避免资源泄漏和内存泄漏。
  • 文件大小获取:原代码没有调用stat函数,导致filesize是未初始化的垃圾值,现在通过拼接完整路径调用stat来获取正确的文件大小。
  • 安全字符串处理:用strncpy代替strcpy,并手动添加字符串结束符,防止文件名过长导致缓冲区溢出。

内容的提问来源于stack exchange,提问作者Sulav k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:13:55