Search code examples
cdynamicstructmallocrealloc

realloc struct of array inside function


I have made a library program to store movies in and using dynamic memory allocation for my struct array without success. Adding the first record (movie) works fine, but after the second the values are just messed up characters.

There is not really much more to say than showing my code.

The problem is that I can't realloc inside my function addmovie();

But if I put this line:

movie = (struct movies *) realloc(movie, (records+1) * sizeof(struct movies)); 

Right before calling addmovie(); function it seems to work, why?

/* Global variables */
int records = 0; // Number of records

struct movies{
    char name[40];
    int id;
};

addmovie(struct movies **movie)
{
    int done = 1;
    char again;
    int index;

    while (done)
    {
        index = records;
        records++; // Increment total of records

        struct movies *tmp = (struct movies *) realloc(movie, (records+1) * sizeof(struct movies));

        if (tmp)
            *movie = tmp;

        system("cls");
        fflush(stdin);
        printf("Enter name of the Movie: ");
        fgets(movie[index].name, 40, stdin);

        fflush(stdin);
        printf("Enter itemnumber of the Movie: ");
        scanf("%d", &movie[index].id);

        printf("\nSuccessfully added Movie record!\n");

        printf("\nDo you want to add another Movie? (Y/N) ");
        do
        {
            again = getch();
        } while ( (again != 'y') && (again != 'n') );

        switch ( again )
        {
        case ('y'):
            break;

        case ('n'):
            done = 0;
            break;
        }
    } // While
}

int main()
{
    int choice;

    struct movies *movie;
    movie = (struct movies *) malloc(sizeof(struct movies)); // Dynamic memory, 68byte which is size of struct

    while (done)
    {
        system("cls");
        fflush(stdin);
        choice = menu(); //returns value from menu

        switch (choice)
        {
        case 1:
            addmovie(movie);
            break;
        }

    } // While

    free(movie); // Free allocated memory
    return 0;
}

Solution

  • C is a pass-by-value language. When you do:

    movie = (struct movies *) realloc(movie, (records+1) * sizeof(struct movies));
    

    In your function, movie from main() isn't affected at all. You need to pass a pointer-to-a-pointer:

    void addmovie(struct movies **movie)
    

    and then modify the pointer's contents:

    struct movies *tmp = realloc(...)
    if (tmp)
       *movies = tmp;
    

    Note that it's also important not to assign the return value of realloc back to the variable to passed to it - you might end up leaking.

    Check the comp.lang.c FAQ question 4.8 for a complete explanation.