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
相关产品推荐
相关产品推荐

