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

时间:2015-07-09 16:53:51

标签: 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 = {&#34;。&#34;,&#34; ..&#34;,&#34; File1&#34;,&#34; File2&#34;}

但它是:

  

Array = {&#34; File2&#34;,&#34; File2&#34;,&#34; File2&#34;,&#34; File2&#34;}

问题1:

char **string_array = NULL;

我注意到这个&#34;指向指针&#34;概念被大量使用,我认为我误解了为什么/如何使用它。我认为指向任何东西的指针只是一个指针(一个内存块,它保存一个地址)。为什么我们关心这个特定指针指向另一个指针?这只是符号还是编译器对待**与*?

不同

问题2:

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

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

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

3 个答案:

答案 0 :(得分:1)

如果您阅读the readdir(3) manual page,您会看到:

  

对于同一目录流,readdir()返回的数据可能被覆盖覆盖<{strong>到readdir()

  

成功时,readdir()返回指向dirent结构的指针。 (此结构可能静态分配 ......

[强调我的]

这意味着无论您拨打readdir多少次,您获得的指针都可能相同。这也意味着你每次存储的指针都是相同的。

您需要复制实际的字符串而不仅仅是指针。这可以通过例如strdup

答案 1 :(得分:1)

string_array[strcount++] = current_directory;

您正在设置string_array中的每个元素指向current_directory,当您退出循环时,它指向字符串“File2”。你的第二个问题 - “为什么我们不为字符串数组的各个成员分配内存?” - 正是在点上。也许你想要这样的东西:

string_array[strcount++] = strdup(current_directory);

答案 2 :(得分:1)

第一个问题是您的代码不会复制# shrimp.rb class Shrimp def initialize(app) @app = app end def call(env) @app.call(env) end end # config.ru require 'rack' require 'rack/lobster' require 'shrimp' use Shrimp run Rack::Lobster.new </pre> 返回的ep->d_name。这就是您的代码打印最后返回的项目的原因。

您可以通过在readdir上调用strdup或自行复制字符串来解决问题:

current_directory

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

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