closedir()导致更改现有列表的节点

closedir()导致更改现有列表的节点,c,list,closedir,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);

这是我函数的简化代码:

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/");
我在主要功能中使用的:

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/");
问题是第二次调用函数会更改第一次调用中返回的列表元素。源文件的元素在ListFileIndirectoryTest/之后发生更改;被称为

但当我从函数体中删除closedirdir时,一切都正常工作,并且sourceFiles的元素没有改变

我准备了一个简单的程序,你可以看看会发生什么。 示例结果:

如您所见,SourceFiles content 1和SourceFiles content 2是不同的。第一个在调用listFilesInDirectorydest/之前打印,第二个在调用之后打印。但如果我从函数中删除closedirdir,则所有函数都会正常工作:


这是怎么回事?为什么会这样?如何预防?我不应该在我的程序中使用closedir吗?

问题似乎是您创建的节点的名称直接来自entry->d\u name。但条目是堆栈分配的结构,一旦退出ListFileIndirectory,它将变得无效

一个简单的解决方法:

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

但我建议您检查所有内容的返回值:opendir、closedir以及strdup。

请发布createNode和addToList的代码。其余代码放在这里。为什么在删除closedir后退出函数时,struct不会变为无效?关闭目录是否会销毁readdirdir返回的所有结构?这是否意味着没有closedir,readdirdir返回的所有struct dirent仍在内存中?我应该把freentry作为循环中的最后一件事吗?当然,我会检查给定函数的返回值。正如我在文章中所说,这段代码尽可能地简化了。在访问内存时,可能会发生许多不应该发生的事情。例如,在我的计算机上,我得到的是乱码输出,而不是目录条目。这可能因编译器、操作系统等不同而有所不同。您必须理解,定义目录结构的方式意味着它的生命周期直到函数堆栈分配内存结束,新函数调用将创建一个堆栈。您需要的是堆分配的内存,它在显式释放之前保持有效。您只能释放堆内存,堆栈可以释放自身。原则上,您也可以在堆上分配结构w/malloc。从ListFileIndirectory返回后,创建的列表按预期工作。当我再次调用一个函数时,我以前的列表会改变。但是你说结构存在直到函数结束,所以当列表被返回时,它应该在那一刻被破坏,因为结构被破坏了,但是没有。它在创建另一个列表后被破坏。这对我来说毫无意义。特别是,我不明白为什么closedir会影响这段代码,为什么创建另一个列表会干扰第一个列表。实际上,内存并没有以某种方式归零。从C编程约定的意义上讲,它已经被破坏了,使用这个内存地址做任何其他事情都是不安全的。它可能会被用来做其他的事情,那就是奇怪的事情开始发生的时候。