简体   繁体   中英

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);

First of all, please note that some structures, ie

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, ie:

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, ie:

free Cabin
free Skicards in a loop
free Booking

You can do:

void removeBooking(Booking *booking)
{   
    for (int i = 0; i < booking->nrOfPerson; i++)
    {   
        free(booking->arrPerson[i].ptrSkicard);
        booking->arrPerson[i].ptrSkicard = NULL;
    }
    free(booking->cabin);
    booking->cabin = NULL
    free(booking);
}

Set the booking pointer to NULL , in the caller function, after calling removeBooking() function or as an alternative you can pass the address of booking pointer and dereference it while freeing other associated allocations and at the end of removeBooking() set *booking = NULL .

You've freed memory taken by Booking (pointed by booking ), then you tried to access it.

free(booking);
printf("%d", booking->nrOfPerson);

It's an undefined behavior. Not sure what you want to accomplish here, because your deallocation doesn't change nrOfPerson or ptrSkicard . free() doesn't change pointer.

Note that your function passes point by value, so you can't change pointer outside of it. if you need that, then:

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

if you are going to free booking(structure),then you can memset like above once check this.thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM