closeir() 会导致现有列表的节点发生变化

标签 c list closedir

这是我的函数的简化代码:

myList* listFilesInDirectory(char* path) {
    DIR* dir = opendir(path);
    myList* list = createList();
    struct dirent* entry;

    while ((entry = readdir(dir)) != NULL) {
        myNode* node = createNode(entry->d_name);
        addToList(list, node);
    }
    closedir(dir);
    return list;
}

我在主函数中使用:

myList* sourceFiles = listFilesInDirectory("source/");
myList* destFiles = listFilesInDirectory("dest/");

问题是函数的第二次调用更改了第一次调用中返回的列表元素。调用 listFilesInDirectory("dest/"); 后,sourceFiles 的元素发生更改。

但是当我从函数体中删除 linedir(dir) 时,一切都会正常工作,并且 sourceFiles 的元素不会更改。

我准备了一个简单的程序https://pastebin.com/9pTYmpm2这样你就可以看到会发生什么。 结果示例:

Result of test program

如您所见,SourceFiles 内容 1SourceFiles 内容 2 是不同的。第一个是在调用 listFilesInDirectory("dest/") 之前打印的,第二个是在调用之后打印的。但是,如果我从函数中删除 closedir(dir) ,则一切正常:

Result after removing closedir(dir)

这是怎么回事?为什么会发生这种情况?如何预防呢?我不应该在程序中使用 linedir() 吗?

最佳答案

问题似乎是您正在使用直接来自 entry->d_name 的名称创建节点。但条目是堆栈分配的struct,一旦退出listFilesInDirectory,它将变得无效。

一个简单的修复:

while ((entry = readdir(dir)) != NULL) {
        myNode* node = createNode(strdup(entry->d_name));
        addToList(list, node);
}

但我建议您检查所有内容的返回值:opendirlinedir 以及 strdup

关于closeir() 会导致现有列表的节点发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49588947/

相关文章:

c++ - std::vector 与 std::list 的插入频率和动态大小

closedir()导致core dumped

c - 为什么 fscanf/scanf 正在更改 Ideone.com 上先前扫描的变量的值?

c - lint 错误 18 "Symbol ' CsiNetInit(void)' 重新声明(精度)与第 21 行冲突

c - 浮点值、运算符和函数有多不可靠?

list - 如何计算列表中项目的出现次数

list - 尝试在 Haskell 中编写一个函数,根据 -Wall 我需要一个匹配的模式 (_ :_:_) _ What does this pattern mean and why do I need it?

c - 使用 opendir()、readdir() 和 closedir() 高效地遍历目录树

c - 使用 wordwrap 2 的最佳消息框大小