将目录文件名存入二维数组时触发Segmentation fault (SIGSEGV)求助
解决目录文件路径存储到二维数组时的段错误问题
代码中的核心问题
- 函数未声明引发未定义行为:
main中调用filestoarray前未声明该函数,C会隐式将其视为返回int的函数,但实际函数返回void,触发未定义行为。 - 递归逻辑错误:
- 处理
./..时未跳过后续逻辑,导致未初始化的path被传入递归调用,引发非法内存访问。 - 未判断条目是否为目录就递归,普通文件会导致
opendir失败,且无效路径可能触发段错误。
- 处理
- 数组越界访问:用
static int i累加索引,但未检查i是否超过SIZE1(100),超出后会写入数组越界区域。 - printf输出错误:直接传递二维数组名
tags给printf("%s"),实际应输出tags[i],否则会打印垃圾内容或重复输出首个路径。 - 缓冲区溢出风险:
getcwd(wd,200)若路径过长会返回NULL,导致wd内容异常;strcat拼接路径时未做长度检查,可能溢出缓冲区。
修复后的代码
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <dirent.h> #include <string.h> #define SIZE1 100 #define SIZE2 2500 // 提前声明函数,避免隐式声明问题 void filestoarray(char* basePath, char arr[SIZE1][SIZE2], int *count); int main(int argc, char *argv[]) { char tags[SIZE1][SIZE2] = {0}; // 初始化数组,避免垃圾值 int i, count = 0; char wd[256]; // 增大缓冲区,适配更长路径 if (getcwd(wd, sizeof(wd)) == NULL) { perror("getcwd failed"); return 1; } filestoarray(wd, tags, &count); // 只打印实际存储的路径 for (i = 0; i < count; i++) { printf("%s\n", tags[i]); } return 0; } void filestoarray(char* basePath, char arr[SIZE1][SIZE2], int *count) { char path[SIZE2]; // 与数组元素大小一致,避免溢出 struct dirent *dp; DIR *dir = opendir(basePath); if (!dir) { return; } while ((dp = readdir(dir)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { continue; // 跳过当前/上级目录,直接进入下一次循环 } // 用snprintf安全拼接路径,Windows下可将"/"改为"\\" snprintf(path, sizeof(path), "%s/%s", basePath, dp->d_name); // 检查数组是否已满,避免越界 if (*count >= SIZE1) { printf("Warning: 数组已满,无法存储更多路径\n"); closedir(dir); return; } strcpy(arr[*count], path); (*count)++; // 仅当条目为目录时递归 if (dp->d_type == DT_DIR) { filestoarray(path, arr, count); } } closedir(dir); }
关键修复说明
- 用
int *count替代static int i,通过指针传递计数,避免递归中静态变量的累积问题。 - 使用
snprintf拼接路径,确保缓冲区不会溢出。 - 新增数组满额检查,防止越界访问。
- 仅对目录类型条目递归,避免无效的
opendir调用。 - 初始化数组为0,消除未存储位置的垃圾值。
- 调整
printf逻辑,仅打印实际存储的路径。
内容的提问来源于stack exchange,提问作者user20137453
相关产品推荐
相关产品推荐

