在 CentOS 下使用 readdir() 出现 段错误(Segmentation fault),通常不是系统本身的问题,而是使用方式不正确。下面按「最常见原因 → 排查方法 → 正确示例」来说明。
opendir() 打开,或打开失败DIR *dir = opendir("/some/path");
if (dir == NULL) {
perror("opendir");
return -1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) { // 如果 dir 是 NULL,直接崩
...
}
✅ 正确做法:必须先检查 opendir() 返回值
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);
}
struct dirent 指针未初始化或已 freestruct dirent *entry;
readdir_r(dir, entry, &entry); // ❌ entry 未分配内存
✅ 正确用法(readdir_r):
struct dirent ent;
struct dirent *result;
readdir_r(dir, &ent, &result);
closedir() 后还调用 readdir()closedir(dir);
readdir(dir); // ❌ 段错误
CentOS(尤其 CentOS 7)使用 glibc 2.17,部分老代码:
readdir() / readdir64()_FILE_OFFSET_BITS=64)可能导致结构体大小不匹配 → 段错误。
✅ 建议:
dirent64readdir()#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
gcc -g test.c -o test
gdb ./test
run
bt
ulimit -c unlimited
./test
你可以贴出:
cat /etc/redhat-release)ldd --version)我可以直接告诉你哪一行会导致段错误,以及怎么改。