Paul
Paul

Reputation: 515

realloc() on array of structs gives invalid next size

I have this function. As you can see, everything is being done in the function, I'm not allocating in the main and then passing anything to it (I'll only return the pointer to the array once the function is done). The function in itself (with a fixed size for the array) works, but the realloc fails.

struct database *parse() {

    int i = 0;
    int n = 1;

    FILE *dbase = (fopen(PATH, "r"));
    if (dbase == NULL) {
        fprintf(stderr, ERRORE_APERTURA);
        exit(EXIT_FAILURE);
    }

    struct database *database_array =  calloc(20*n, sizeof(struct database));
    if (database_array == NULL) {
        fprintf(stderr, "Impossibile allocare memoria\n");
        exit(EXIT_FAILURE);
    }

    while (feof(dbase) == 0) {
        fscanf(dbase, "%[^:]:%[^:]:\n", database_array[i].user, database_array[i].password);
        database_array[i].iswritten = 1;
        i++;
        if (i > 20*n) {
            n++;
            struct database *new_database_array = realloc(database_array, sizeof(struct database)*(20*n));
            database_array = new_database_array;
        }
    }
    database_array[++i].iswritten = 0;

    fclose(dbase);  
    return database_array;
}

I tried reading other explanations, but I can't understand what's wrong here.

The array I allocated with calloc is initially 20. then, when it's filled, I want it to double in size, so I use n, which will be 2, by 20, so 40.

The frustrating thing is that I tried reallocating an array of struct with a simpler program, and doing THE SAME THING works without any problem:

#include <stdio.h>
#include <stdlib.h>

struct prova  {

    int a;

    int b[10];
};


int main() {

    struct prova* array_struct = calloc(10, sizeof(struct prova));

    array_struct[0].a = 2;

    struct prova* tmp = realloc(array_struct, sizeof(struct prova) * 20);

    free(array_struct);
    array_struct = tmp;

    array_struct[1].b[1] = 3;

    printf("a = %d", array_struct[0].a);
    printf("b = %d\n", array_struct[1].b[1]);

    return 0;   
}

What am I not seeing? (Please nevermind the fact that I'm not checking if realloc returns NULL, I'll add that later)

Upvotes: 0

Views: 182

Answers (1)

David Schwartz
David Schwartz

Reputation: 182893

struct database *new_database_array = realloc(database_array, sizeof(struct database)*(20*n));
free(database_array);

You can't both reallocate something and deallocate it. You can do either, but once you've done either, the previous allocation no longer exists, so you can't do the other.

After the first line of code above, the value of database_array should not be used anymore because it may not be valid.

Upvotes: 2

Related Questions