这是我的功能的简化代码:

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/");


问题在于函数的第二次调用更改了在第一次调用中返回的列表的元素。 sourceFiles的元素在调用listFilesInDirectory("dest/");之后变为。

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

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

c - closeir()导致现有列表节点的更改-LMLPHP

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

c - closeir()导致现有列表节点的更改-LMLPHP

这里发生了什么?为什么会发生?怎么预防呢?我不应该在程序中使用closedir()吗?

最佳答案

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

一个简单的解决方法:

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


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

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

10-11 21:31