Search code examples
cpointersmemory-managementstructfree

De-allocate memory of structs inside a struct in C


I have built a program that have severals structs inside it. We have the "base" struct called Booking that is going to contain all information needed for making a reservation at a vacation location. It looks like this:

typedef struct {
    char forename[NAME_LEN];
    char surname[NAME_LEN];
    char socialNr[SOCIAL_NR];
    int nrOfPerson;
    Person arrPerson[MAX_GUEST];
    int rentPeriod[2];
    int totalCost;
    Cabin *cabin;
    int seniorCard;
    int juniorCard;
    int childCard;

} Booking;

Booking also contains 2 other structs, one array of Persons that will hold up to 8 people max that can be in a booking, and also a struct for a Cabin. Both of these ones looks like this:

typedef struct {
    char forename[NAME_LEN];
    char surname[NAME_LEN];
    char socialNr[SOCIAL_NR];
    Skicard *ptrSkicard;
    int age;

} Person;

 typedef struct {
    int nr;
    int cost;
    int booked[WEEKS];
    int typeOfCabin;

} Cabin;

And the person struct also holds an additional struct for a skicard which looks like this:

typedef struct {
    int price;

} Skicard;

My questions is how I now correctly de-allocate the memory of all of these ones when they are inside each other?

I have started and I thought I have to go from inside an move out so I tried to remove all the skicards first, then I would remove the Persons, and then the cabin and last the booking itself.

void removeBooking(Booking *booking)
{
    for (int i = 0; i < booking->nrOfPerson; i++)
    {
        free(booking->arrPerson[i].ptrSkicard);
    }
    free(booking);
    printf("%d", booking->nrOfPerson);
}

But I'm stuck here. How do I do this properly?

Edit: Forgot to show how the allocation was done.

    Booking *allBookings = (Booking *)malloc(sizeof(Booking) * 1);
    Cabin *ptrCabin = (Cabin *)malloc(sizeof(Cabin) * 1);
    Skicard *ptrSkicard = (Skicard *)malloc(sizeof(Skicard) * 1);

Solution

  • First of all, please note that some structures, i.e.

    Person arrPerson[MAX_GUEST];
    

    are integral part of Booking structure and should not be neither allocated nor deallocated -- those will be allocated/deallocated with Booking structure.

    But the structures we keep just a pointer to, i.e.:

    Skicard *ptrSkicard;
    

    or

    Cabin *cabin;
    

    should be allocated and deallocated.

    Basically you should deallocate in reverse order of your allocation. For example, allocation could be:

    malloc Booking
    malloc Skicards in a loop
    malloc Cabin
    

    So the deallocation should be in reverse, i.e.:

    free Cabin
    free Skicards in a loop
    free Booking