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

将目录文件名存入二维数组时触发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);
}

关键修复说明

  1. 用int *count替代static int i,通过指针传递计数,避免递归中静态变量的累积问题。
  2. 使用snprintf拼接路径,确保缓冲区不会溢出。
  3. 新增数组满额检查,防止越界访问。
  4. 仅对目录类型条目递归,避免无效的opendir调用。
  5. 初始化数组为0,消除未存储位置的垃圾值。
  6. 调整printf逻辑,仅打印实际存储的路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:31:21