如何在c中正确使用scandir()?

我正在试图将文件列表存储在char **variables中。

scandir()完成正确,但是在尝试打印char **时出现分段错误。

代码如下:

int main() { char** fileList; int noOfFiles; char* path = "."; makeList(&fileList, &noOfFiles, path); return 0; } void makeList(char ***fileList, int* noOfFiles, char* path){ struct dirent **fileListTemp; *noOfFiles = scandir(path, &fileListTemp, NULL, alphasort); int i; fileList = (char***)malloc(sizeof(char***)); *fileList = (char**)malloc(*noOfFiles * sizeof(char*)); printf("total: %d files\n",*noOfFiles); for(i = 0; i < *noOfFiles; i++){ *fileList[i] = (char*)malloc(strlen(fileListTemp[i] -> d_name) *sizeof(char)); strcpy(*fileList[i], fileListTemp[i] -> d_name); printf("%s\n",*fileList[i]); } return; } 

打印2个文件名后,这会导致分段错误。

输出:

总共:27个文件。

..

.jv

分割故障(核心转储)

Solutions Collecting From Web of "如何在c中正确使用scandir()?"

函数scandir()为你分配内存。

你不需要分配任何内存。 你需要释放由scandir()返回给你的内存。

你的代码调用: *noOfFiles = scandir(path, &fileListTemp, NULL, alphasort);

返回时, noOfFiles将包含path目录中的目录条目数, fileListTemp将指向已分配字符串的指针数组,每个指向包含文件的以null结尾的名称的已分配块。

如果您的目录中包含“FirstFile.txt”,“AnotherFile.txt”,“ThirdFile.txt”等文件,那么从scandir()返回时, noOfFiles将被设置为5 ,三个文件加上两个更为“”。 和“..”目录条目。 如果您不通过“alphasort”,则条目将毫无特别地排列。 (实际上这有点不正确,它们将按目录文件名的顺序依次取决于最初创建文件的顺序。)

因为你传递了'alphasort',你应该看到以下顺序的条目(我明确地显示了空字节串终止符:

 fileListTemp[0] == ".\0" fileListTemp[1] == "..\0" fileListTemp[2] == "AnotherFile.txt\0" fileListTemp[3] == "FirstFile.txt\0" fileListTemp[4] == "ThirdFile.txt\0" 

所以fileListTemp指向一个分配的内存块,持有五个(char *)指针。 五个(char *)指针中的每一个都指向一个包含空终止的目录条目名称的已分配内存块。

这是块分配的内存。

你可以使用这个分配的内存,直到你完成它,然后你在数组的每个入口处调用free(),然后在数组本身的free()后面调用free()。

您必须释放每个条目以及数组本身。 他们都是独立分配的记忆斑点。

当你完成清单你应该:

 for (int i = 0; i < noOfFiles; i++) { free(fileListTemp[i]; } free(fileListTemp); 

这是一个古老的问题,但是由于我遇到了这个问题,并没有像手册页那样有效地解决我的问题,所以我抄袭手册页中的代码片段,作为未来的新答案。

  #include <dirent.h> int main(void) { struct dirent **namelist; int n; n = scandir(".", &namelist, NULL, alphasort); if (n < 0) perror("scandir"); else { while (n--) { printf("%s\n", namelist[n]->d_name); free(namelist[n]); } free(namelist); } } 

我不确定这是否是问题,但您必须为空终止分配另一个字节:

 *fileList[i] = (char*)malloc(strlen(fileListTemp[i] -> d_name + 1) *sizeof(char));