在 Debian(或其他 Linux)系统上,使用 opendir() / readdir() / closedir() 处理目录时,“内存泄漏”通常不是 opendir 本身的问题,而是没有正确配对关闭目录流,或错误管理 readdir 返回的指针。下面按常见错误和正确做法说明。
opendir,不 closedirDIR *dir = opendir("/tmp");
if (!dir) { perror("opendir"); return; }
// 忘记 closedir(dir);
✅ 正确做法:
DIR *dir = opendir("/tmp");
if (!dir) {
perror("opendir");
return;
}
/* 使用 dir */
closedir(dir);
DIR *dir = opendir(path);
if (!dir) return;
while ((ent = readdir(dir))) {
if (some_error)
return; // ❌ 泄漏
}
closedir(dir);
✅ 正确写法(goto 或封装):
DIR *dir = opendir(path);
if (!dir) return;
while ((ent = readdir(dir))) {
if (some_error)
goto cleanup;
}
cleanup:
closedir(dir);
struct dirent *ent = readdir(dir);
free(ent); // ❌ 错误
⚠️ readdir() 返回的是 静态/内部缓冲区指针,不要 free。
✅ 正确:
strdup() 复制名字char *name = strdup(ent->d_name);
struct dirent ent;
readdir_r(dir, &ent, &result); // 可能溢出
✅ 推荐:
readdir()(线程安全可用 readdir_r 但需正确分配)#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
void list_dir(const char *path) {
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return;
}
struct dirent *ent;
while ((ent = readdir(dir)) != NULL) {
printf("%s\n", ent->d_name);
}
closedir(dir);
}
sudo apt install valgrind
valgrind --leak-check=full ./your_program
gcc -g -O0 main.c -o main
| 误解 | 事实 |
|---|---|
| opendir 会泄漏内存 | 不会,关键是 closedir |
| readdir 要 free | 不需要 |
| DIR* 是普通指针 | 是系统资源,必须关闭 |
| 程序退出就不用关 | 不优雅,长期运行必漏 |
如果你有 具体代码 或是在 C / C++ / 某框架 里用 opendir,可以把代码贴出来,我可以帮你逐行检查是否泄漏。