温馨提示×

centos readdir为何报段错误

小樊
33
2026-10-23 17:25:26
栏目: 智能运维

在 CentOS 下使用 readdir() 出现 段错误(Segmentation fault),通常不是系统本身的问题,而是使用方式不正确。下面按「最常见原因 → 排查方法 → 正确示例」来说明。


一、最常见的段错误原因

1️⃣ 目录没有用 opendir() 打开,或打开失败

DIR *dir = opendir("/some/path");
if (dir == NULL) {
    perror("opendir");
    return -1;
}

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {  // 如果 dir 是 NULL,直接崩
    ...
}

✅ 正确做法:必须先检查 opendir() 返回值


2️⃣ 把 readdir() 的返回值直接当字符串使用

char *name = readdir(dir)->d_name; // ❌ 危险
printf("%s\n", name);

如果 readdir() 返回 NULL,->d_name 直接段错误。

✅ 正确写法:

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    printf("%s\n", entry->d_name);
}

3️⃣ struct dirent 指针未初始化或已 free

struct dirent *entry;
readdir_r(dir, entry, &entry); // ❌ entry 未分配内存

✅ 正确用法(readdir_r):

struct dirent ent;
struct dirent *result;
readdir_r(dir, &ent, &result);

4️⃣ 目录已被 closedir() 后还调用 readdir()

closedir(dir);
readdir(dir); // ❌ 段错误

5️⃣ 32/64 位或 glibc 版本差异(CentOS 特有坑)

CentOS(尤其 CentOS 7)使用 glibc 2.17,部分老代码:

  • 混用 readdir() / readdir64()
  • 宏定义不一致(_FILE_OFFSET_BITS=64)

可能导致结构体大小不匹配 → 段错误。

✅ 建议:

  • 不要手动定义 dirent64
  • 统一用 readdir()

二、标准正确示例(CentOS 可用)

#include <stdio.h>
#include <dirent.h>

int main() {
    DIR *dir = opendir(".");
    if (!dir) {
        perror("opendir");
        return 1;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n", entry->d_name);
    }

    closedir(dir);
    return 0;
}

编译:

gcc test.c -o test

三、快速排查段错误的方法

✅ 1. 用 gdb 定位

gcc -g test.c -o test
gdb ./test
run
bt

✅ 2. 打开核心转储

ulimit -c unlimited
./test

四、如果你愿意,我可以更具体地帮你

你可以贴出:

  • 你的 C/C++ 代码片段
  • CentOS 版本(cat /etc/redhat-release)
  • glibc 版本(ldd --version)

我可以直接告诉你哪一行会导致段错误,以及怎么改。

0 踩