Home > Software design >  Dynamic array allocation returns only last element in all indices C
Dynamic array allocation returns only last element in all indices C

Time:11-14

Okay so I am trying to input data from text file into dynamic arrays of strings. Each data tuple has 6 attributes. Hence 6 arrays. The problem is that when I populate all the arrays, It prints right values in loop. But when I try to access any of the array's element outside the loop, it gives the last word of text file as output. I have tried all the solutions available and none of them seems to work.

The code is:

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.");
        }
    }
}

CodePudding user response:

For starters the expression used as an initializer in this declaration

int length_of_arrays = sizeof presenters / sizeof *presenters;

does not make a sense because it is equivalent to

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

In this while loop

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

all elements dates[i] point to the same array

dates[i] = buffer;

So this loop

        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.

        }

outputs what the last was stored in the array buffer.

It seems you need to allocate arrays that will be pointed to by the elements dates[i] and copy there strings from buffer.

Also the function is very complicated. You should combine all parameters starting from the third parameter in a structure.

Take into account that as all the pointers are passed by value then the reallocation of memory within the function will not be reflected in the pointers used as arguments.

CodePudding user response:

So I figured it out. There were 2 issues. 1: mentioned by Ehmad i.e We need to use strcpy() while using pointers and the other was that at every step of loop, each index of array needed to have memory allocated separately.

CodePudding user response:

You cannot do

array[i] = buffer;

because the buffer is a char array and stores the address of the char array. When you assign its value to a new variable, you are basically copying its address to a new variable. That's why each index of your array is pointing towards the same array that holds the latest value from the file.

You need to perform a deep copy by copying the contents of buffer variable either by strcpy or something else.

  • Related