c - 在 C 中动态填充字符串数组

标签 c arrays pointers

我正在使用教程制作一段代码,该代码读取目录并使用文件名动态填充数组。

首先,下面的代码不起作用,因为它只用一个文件名填充整个数组——目录中的最后一个文件名。其次,我无法理解它的某些部分。在代码之后,我包括了一个问题列表。

char** directory_string_array(char* directory){
    DIR *dp;
    struct dirent *ep;
    dp = opendir(directory);
    char* current_directory;

    char **string_array = NULL;
    int i = 0, strcount = 0;


    if (dp !=NULL){
        while (ep = readdir (dp)){
            //pointer to char array which contains name of current file
            current_directory = ep->d_name;
            //allocate additional memory to string_array
            string_array = (char**) realloc(string_array, (strcount+1) * sizeof(char*));
            string_array[strcount++] = current_directory;
        }
        (void) closedir(dp);

    } else{
        perror("Couldn't open the directory");
    }
    //print the array to check it
    for(i = 0; i <strcount; i++){
        printf("strarray[%d] == %s\n", i, string_array[i]);
    }
    //free memory (this will later be outsourced to another file - I know that this will free memory from the thing I am trying to return
    for(i = 0; i < strcount; i++){
        free(string_array[i]);
    }
    free(string_array);

    return string_array;
}

结果数组应该是:

Array = {".", "..", "File1", "File2"}

但它是:

Array = {"File2", "File2", "File2", "File2"}

问题 1:

char **string_array = NULL;

我注意到这个“指向指针的指针”概念被广泛使用,我想我误解了为什么/如何使用它。我认为指向任何东西的指针只是一个指针(一个存储某物地址的内存块)。为什么我们关心这个特定的指针指向另一个指针?这只是符号还是编译器将 ** 与 * 区别对待?

问题 2:

string_array = (char**) realloc(string_array, (strcount+1) * sizeof(char*));

所以这里我们额外分配了一 block 和char*一样大的内存块(我认为是和char**一样大)。但是,为什么我们不为字符串数组的各个成员分配内存呢?那我们接下来为什么不用这行代码,例如:

string_array[0] = malloc(sizeof(char*));

最佳答案

第一个问题是您的代码不重复 readdir 返回的 ep->d_name。这就是您的代码打印最后返回的项目的原因。

您可以通过在 current_directory 上调用 strdup 或自己复制字符串来修复它:

size_t len = strlen(current_directory)+1;
string_array[strcount] = malloc(len);
strcpy(string_array[strcount], current_directory);
strcount++;

您还应该将函数一分为二 - 一个创建数组,一个释放它。这样你就可以避免访问释放内存的未定义行为:

char** directory_string_array(char* directory, size_t *strcount){
    ...
    //print the array to check it
    for(i = 0; i < *strcount; i++){
        printf("strarray[%d] == %s\n", i, string_array[i]);
    }
    return string_array;
}
void free_directory_string_array(char **string_array, size_t strcount) {
    for(i = 0; i < strcount; i++){
        free(string_array[i]);
    }
    free(string_array);
}

关于c - 在 C 中动态填充字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31323768/

相关文章:

c - 使用 'printf' 在 C 中打印 % 符号

c - 指针和指针功能

arrays - 如何借助 Julia 中的指针访问和更改数组中的元素?

c++ - C++中对数组的误解

c++ - 指向相同类型的对象

c - 将字符串的内容解析为子字符串

c++ - 在 C++ 中使用数组时出现奇怪的错误

c - 以良好的方式在 C 中分配和释放内存

c++ - Valgrind 在通过指向结构的指针访问结构成员时提示无效读取

java - 位移时间复杂度