动态数组分配仅返回所有索引中的最后一个元素 C

Posted

技术标签:

【中文标题】动态数组分配仅返回所有索引中的最后一个元素 C【英文标题】:Dynamic array allocation returns only last element in all indices C 【发布时间】:2021-12-25 02:29:36 【问题描述】:

好的,我正在尝试将文本文件中的数据输入到字符串的动态数组中。每个数据元组有 6 个属性。因此有 6 个数组。问题是当我填充所有数组时,它会在循环中打印正确的值。 但是当我尝试访问循环外的任何数组元素时,它会给出文本文件的最后一个单词作为输出。我已经尝试了所有可用的解决方案,但似乎都不起作用。

代码是:

int  n(FILE **fp, int size,  char **presenters, char **birth_numbers, char **room_codes, 
        char **authors, char **post_titles, char **presentation_types, char **presentation_times, 
        char **dates)
    // Buffer to get input from the file.
    char buffer[200];
    // To check if the file is open or not
    if (*fp == NULL)
        printf("File not Open");
    
    else
        char *file = "konferencny_zoznam.txt";
        fseek(*fp, 0, SEEK_SET);
        if (size >= 1)
            int length_of_arrays = sizeof presenters / sizeof *presenters;
            if (length_of_arrays > 1)
                printf("in null if");
                free(presenters);
                free(birth_numbers);
                free(room_codes);
                free(authors);
                free(post_titles);
                free(presentation_times);
                free(presentation_types);
                free(dates);
            

            presenters = malloc((size+1)* sizeof(char*));
            birth_numbers = malloc((size+1)* sizeof(char*));
            room_codes = malloc((size+1)* sizeof(char*));
            authors = malloc((size+1)* sizeof(char*));
            post_titles = malloc((size+1)* sizeof(char*));
            presentation_times = malloc((size+1)* sizeof(char*));
            presentation_types = malloc((size+1)* sizeof(char*));
            dates = malloc((size+1)* sizeof(char*));

            const unsigned MAX_BUFFER_LENGTH = 256;
            char buffer[MAX_BUFFER_LENGTH];
            int i = 0, len = 0;
        

            while(fgets(buffer, MAX_BUFFER_LENGTH, *fp))
                // len = strlen(buffer)+1;
                presenters[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                birth_numbers[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                room_codes[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                authors[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                post_titles[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                presentation_times[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                presentation_types[i] = buffer;
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);
                dates[i] = buffer;
                printf("buffer : %s", dates[i]);
                fgets(buffer, MAX_BUFFER_LENGTH, *fp);

                i++;
            
       
            for (int i=0; i<8; i++)
                
                printf("presenter[0]: %s", dates[i]);
                // Outputs 20200406 for each iteration which is the last word of file.

            
        
        else 
            printf("File not read already. Consider running command v before.");
        
    


【问题讨论】:

此声明 int length_of_arrays = sizeof presenters / sizeof *presenters;没有意义。相当于 int length_of_arrays = sizeof( char ** ) / sizeof( char * ) ; 每当你分配一个元素时,你就是在分配一个指向函数buffer数组的指针的副本。结果,所有数组的所有元素都指向同一个存储,其内容就是最后存储在那里的内容。更重要的是,当 if (size &gt;= 1) 块的执行终止时,该对象的生命周期结束,这些指针全部悬空。您需要动态分配buffer副本,并为其分配指针。 提示:改为使用结构数组以使其更具可读性。 @AndersK 规则是不要以任何方式使用 struct。 你没有提到你的分配参数 【参考方案1】:

所以我想通了。有2个问题。 1:Ehmad提到的,即我们需要在使用指针时使用strcpy(),另一个是在循环的每一步,数组的每个索引都需要单独分配内存。

【讨论】:

【参考方案2】:

你做不到

array[i] = buffer;

因为缓冲区是一个 char 数组,并且存储了 char 数组的地址。当您将其值分配给一个新变量时,您基本上是将其地址复制到一个新变量中。这就是为什么您的数组的每个索引都指向保存文件中最新值的同一个数组。

您需要通过 strcpy 或其他方式复制缓冲区变量的内容来执行深层复制。

【讨论】:

【参考方案3】:

首先,在此声明中用作初始值设定项的表达式

int length_of_arrays = sizeof presenters / sizeof *presenters;

没有意义,因为它等价于

int length_of_arrays = sizeof( char ** ) / sizeof( char * );

在这个while循环中

        while(fgets(buffer, MAX_BUFFER_LENGTH, *fp))
            // len = strlen(buffer)+1;
            presenters[i] = buffer;
            //..

所有元素dates[i]指向同一个数组

dates[i] = buffer;

所以这个循环

        for (int i=0; i<8; i++)
            
            printf("presenter[0]: %s", dates[i]);
            // Outputs 20200406 for each iteration which is the last word of file.

        

输出最后存储在数组缓冲区中的内容。

您似乎需要分配将由元素 dates[i] 指向的数组并从缓冲区复制字符串。

功能也很复杂。您应该组合结构中从第三个参数开始的所有参数。

考虑到所有指针都是按值传递的,所以函数内内存的重新分配不会反映在用作参数的指针中。

【讨论】:

谢谢。真的有帮助!

以上是关于动态数组分配仅返回所有索引中的最后一个元素 C的主要内容,如果未能解决你的问题,请参考以下文章

怎么动态分配指针数组

在 Visual Studio 2019 C++ 中,如何扩展动态分配的数组以显示其所有元素?

在 C++ 中返回对动态数组元素的引用?

是从动态分配的数组中索引的元素超出了有效范围[duplicate]

JAVA中Vector怎样存放一个动态的二维数组

C语言中的动态内存分配的用法举例