如何在C中正确使用scandir()? [英] How to properly use scandir() in c?

查看:423
本文介绍了如何在C中正确使用scandir()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将文件列表存储在char **变量中.

I am trying to store list of files in a char** variable.

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

scandir() finishes properly but I get a segmentation fault when trying to print the 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个文件名后出现分段错误.

This gives a segmentation fault after printing 2 file names.

输出:

总共:27个文件.

total: 27 files.

..

.j.v

分段错误(核心已转储)

Segmentation fault (core dumped)

推荐答案

函数scandir()为您分配内存.

您不需要分配任何内存.您需要释放scandir()返回给您的内存.

You do not need to allocate ANY memory. You DO need to free the memory returned to you by scandir().

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

返回时,noOfFiles将包含path目录中的目录条目数,并且fileListTemp将指向已分配的指针数组,这些指针指向已分配的 struct dirent 每个blob都有一个 d_name 成员,该成员指向以文件名/目录结尾的以空字符结尾的名称.

On return, noOfFiles will contain the number of directory entries in the path directory, and fileListTemp will point to an allocated array of pointers to allocated struct dirent blobs each of which has a d_name member which points to the null-terminated name of a file/directory.

例如,如果您的目录包含文件"FirstFile.txt","AnotherFile.txt","ThirdFile.txt",则在从scandir()返回时,noOfFiles将被设置为 5 表示三个文件,另外两个表示.".和".."目录条目.如果您不通过"alphasort",则该条目将没有特别的顺序. (实际上,这有点不正确.它们将按照目录文件名条目的顺序,这取决于最初创建文件的顺序.)

If your directory contains the files "FirstFile.txt", "AnotherFile.txt", "ThirdFile.txt", for example, with your call, upon return from scandir(), noOfFiles will be set to 5 for the three files plus two more for the "." and ".." directory entries. THE ENTRIES WILL BE IN NO PARTICULAR ORDER IF YOU DO NOT PASS 'alphasort'. (Actually that's a little incorrect. They will be in the order of the directory filename entries which depends on the order in which the files were originally created.)

由于您通过了'alphasort',因此您应该按以下顺序查看条目(我明确显示了null-byte-string-terminator:

Because you passed 'alphasort' you should see the entries in the following order (I am explicitly showing the null-byte-string-terminator:

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

因此,fileListTemp指向包含五个 struct dirent 指针的已分配内存块.五个 struct dirent 指针中的每一个都指向分配的 struct dirent 块,该块包含以空值结尾的目录 d_name 成员中的条目名称. (即使这是一种简化,因为d_name条目也是一个指针,但它指向已分配块尾部的额外已分配空间,并且条目名称存储在此处.)

So fileListTemp points to a block of allocated memory holding five struct dirent pointers. Each of the five struct dirent pointers points to a struct dirent block of allocated memory containing a null-terminated directory entry name in the d_name member. (Even this is a simplification, because the d_name entry is also a pointer, but it points to extra allocated space at the tail end of the allocated block, and the entry name is stored there.)

这是分配的内存的六个块.

您可以使用此分配的内存,直到完成使用为止,然后在数组的EACH条目上调用free(),然后再调用数组本身的free().​​

You can use this allocated memory until you are done with it, and then you call free() on EACH entry in the array followed by free() of the array itself.

您必须释放每个条目以及数组本身.它们都是独立分配的内存块.

You MUST free every entry as well as the array itself. They are all independently allocated blobs of memory.

完成列表后,您应该:

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

free(fileListTemp);

这篇关于如何在C中正确使用scandir()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆