Search code examples
cmallocdynamic-memory-allocationdynamic-arrayspass-by-value

Dynamic array allocation returns only last element in all indices C


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


Solution

  • 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.