简短结论:readdir(以及 readdir_r)本身在标准 glibc / Debian 实现中不会导致内存泄漏,但用法不对就可能“看起来像泄漏”。
下面分几种情况说明。
readdir ✅ 不会泄漏典型正确写法:
DIR *dir = opendir("/some/path");
if (!dir) { perror("opendir"); return; }
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
要点:
readdir 返回的 struct dirent * 是 由 DIR 内部维护的静态/复用缓冲区free(entry)closedir(dir),资源都会释放✅ 没有内存泄漏
closedirDIR *dir = opendir(path);
while ((entry = readdir(dir)));
// 忘记 closedir
→ DIR 内部缓冲区、fd 都不会释放
→ 会泄漏(fd + 内存)
free(readdir())struct dirent *e = readdir(dir);
free(e); // ❌ 错误
→ 未定义行为
→ 可能崩溃或破坏内部状态
readdirreaddir 不是线程安全的(同一个 DIR 被多个线程共享时)
正确做法:
DIRreaddir_rreaddir_r 呢?struct dirent ent;
struct dirent *res;
readdir_r(dir, &ent, &res);
struct direntclosedir✅ 也不会泄漏
⚠️ 但 POSIX.1-2008 已标记 readdir_r 为过时,推荐 readdir + 多线程隔离
真正容易泄漏的是你自己的代码,例如:
opendir 后提前 return,没 closedirstrdup(entry->d_name) 但没 freescandir 后忘了 free 每个 dirent 和数组valgrindvalgrind --leak-check=full ./your_program
gcc -fsanitize=address| 情况 | 是否泄漏 |
|---|---|
正确使用 readdir + closedir |
❌ 不会 |
忘记 closedir |
✅ 会 |
free(readdir()) |
❌ 错误 |
readdir_r 正确使用 |
❌ 不会 |
自己 malloc/strdup 不释放 |
✅ 会 |
如果你愿意,可以把具体代码贴出来,我可以直接帮你判断是否真有泄漏。