温馨提示×

debian readdir怎样避免内存泄漏

小樊
38
2026-09-10 08:17:15
栏目: 智能运维

在 Debian(或任何 Linux)上使用 readdir / readdir_r 读取目录时,内存泄漏通常不是 readdir 本身造成的,而是使用方式不对。下面按常见场景说明如何避免。


一、使用 readdir(推荐,最简单)

readdir() 返回的是静态内部缓冲区指针,不需要也不能 free。

正确用法 ✅

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

int main() {
    DIR *dir = opendir("/tmp");
    if (!dir) return 1;

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

    closedir(dir);  // 必须关闭
    return 0;
}

常见错误 ❌

free(ent);   // 错误!会导致崩溃或内存问题

✅ 结论:

  • readdir 不要 free
  • 只要 closedir() 就不会泄漏

二、使用 readdir_r(线程安全,但易错)

readdir_r 需要你自己提供 buffer

正确用法 ✅

DIR *dir = opendir("/tmp");
struct dirent *entry;
struct dirent *result;

long name_max = pathconf("/tmp", _PC_NAME_MAX);
if (name_max == -1) name_max = 255;

entry = malloc(offsetof(struct dirent, d_name) + name_max + 1);

while (readdir_r(dir, entry, &result) == 0 && result != NULL) {
    printf("%s\n", entry->d_name);
}

free(entry);   // 你自己 malloc 的,必须 free
closedir(dir);

泄漏点 ❌

  • malloc 了但忘了 free
  • opendir 成功但中途 return,没 closedir

✅ 结论:

  • readdir_r 的 entry 是你分配的 → 必须 free
  • DIR * 必须 closedir

三、C++ 中使用 opendir/readdir

确保异常安全:

#include <dirent.h>
#include <memory>

void foo() {
    std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir("/tmp"), closedir);
    if (!dir) return;

    struct dirent *ent;
    while ((ent = readdir(dir.get())) != nullptr) {
        // 使用 ent
    }
}

四、使用 C++17 std::filesystem(最推荐)

完全不用担心内存泄漏

#include <filesystem>
namespace fs = std::filesystem;

for (auto &p : fs::directory_iterator("/tmp")) {
    std::cout << p.path() << "\n";
}

✅ 无 opendir / readdir
✅ 无手动内存管理


五、常见内存泄漏检查方式(Debian)

sudo apt install valgrind
valgrind --leak-check=full ./your_program

总结

函数 是否需 free 是否需 closedir
readdir ❌ 否 ✅ 是
readdir_r ✅ 是(自己 malloc) ✅ 是
std::filesystem ❌ 否 ❌ 否

如果你愿意,可以把你的代码片段贴出来,我可以直接帮你指出哪里可能泄漏。

0 踩