这是我的函数的简化代码:
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这样你就可以看到会发生什么。 结果示例:
如您所见,SourceFiles 内容 1
和 SourceFiles 内容 2
是不同的。第一个是在调用 listFilesInDirectory("dest/")
之前打印的,第二个是在调用之后打印的。但是,如果我从函数中删除 closedir(dir)
,则一切正常:
这是怎么回事?为什么会发生这种情况?如何预防呢?我不应该在程序中使用 linedir()
吗?
最佳答案
问题似乎是您正在使用直接来自 entry->d_name
的名称创建节点。但条目是堆栈分配的struct
,一旦退出listFilesInDirectory
,它将变得无效。
一个简单的修复:
while ((entry = readdir(dir)) != NULL) {
myNode* node = createNode(strdup(entry->d_name));
addToList(list, node);
}
但我建议您检查所有内容的返回值:opendir
、linedir
以及 strdup
。
关于closeir() 会导致现有列表的节点发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49588947/