在 Ubuntu(Linux)下使用 opendir() 读取目录时,内存泄漏通常不是 opendir() 本身造成的,而是忘记调用对应的 closedir(),或没有正确处理错误路径导致的。下面从原理、常见错误和最佳实践三方面说明。
opendir / closedir 的基本规则#include <dirent.h>
DIR *opendir(const char *name);
int closedir(DIR *dirp);
opendir() 成功时返回 DIR *(内核分配的资源)closedir()NULL,此时不要调用 closedir()DIR *dir = opendir("/tmp");
if (!dir) return;
while (readdir(dir)) {
// 处理
}
// 忘记 closedir(dir);
✅ 结果:目录描述符泄漏(不是传统堆内存,但属于资源泄漏)
DIR *dir = opendir("/tmp");
if (!dir) return;
while ((entry = readdir(dir))) {
if (some_error)
return; // 泄漏!
}
closedir(dir);
DIR *dir = opendir("/tmp");
if (!dir) {
perror("opendir");
return;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
// 处理 entry
}
closedir(dir);
DIR *dir = opendir("/tmp");
if (!dir) return;
int ret = 0;
while ((entry = readdir(dir))) {
if (error) {
ret = -1;
goto cleanup;
}
}
cleanup:
closedir(dir);
return ret;
#include <dirent.h>
#include <memory>
struct DirCloser {
void operator()(DIR* d) const { if (d) closedir(d); }
};
using DirPtr = std::unique_ptr<DIR, DirCloser>;
DirPtr dir(opendir("/tmp"));
if (!dir) { /* error */ }
readdir 的内存说明(很重要)readdir() 不会分配你需要 free 的内存struct dirent * 是 静态/内部缓冲区free(entry)closedir()sudo apt install valgrind
valgrind --leak-check=full ./your_program
关注:
still reachableopen file descriptorls -l /proc/<pid>/fd
opendir 成功 → 必须 closedirreturn / break / goto 前都要考虑关闭readdir 不需要 free如果你愿意,可以把你的代码片段贴出来,我可以帮你逐行检查是否有泄漏风险。