在 C 中取消分配结构内部的内存

De-allocate memory of structs inside a struct in C

我构建了一个程序,其中包含多个结构。我们有一个名为 Booking 的 "base" 结构,它将包含在度假地点进行预订所需的所有信息。它看起来像这样:

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 还包含 2 个其他结构,一个最多可容纳 8 人的 Person 数组,以及一个用于 Cabin 的结构。 这两个看起来像这样:

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;

并且 person 结构还包含一个额外的 skicard 结构,如下所示:

typedef struct {
    int price;

} Skicard;

我的问题是,当所有这些内存在彼此内部时,我现在如何正确地解除分配它们的内存?

我已经开始了,我想我必须从里面搬出去,所以我试着先移除所有的滑雪板,然后我会移除人员,然后是客舱,最后预订本身。

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

但我被困在这里了。我该如何正确执行此操作?

编辑:忘记说明分配是如何完成的。

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

您释放了 Booking 占用的内存(由 booking 指向),然后您尝试访问它。

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

这是一个未定义的行为。不确定你想在这里完成什么,因为你的释放不会改变 nrOfPersonptrSkicardfree() 不改变指针。

请注意,您的函数按值传递点,因此您不能在函数外部更改指针。如果你需要,那么:

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

如果你要免费预订(结构),那么你可以像上面那样进行memset 检查一次 this.thanks

首先,请注意一些结构,即

Person arrPerson[MAX_GUEST];

Booking 结构的组成部分,既不应该被分配也不应该被释放——它们将是 allocated/deallocated 和 Booking 结构。

但是我们只保留指向的结构,即:

Skicard *ptrSkicard;

Cabin *cabin;

应该分配和释放。

基本上,您应该按照分配的相反顺序解除分配。例如,分配可以是:

malloc Booking
malloc Skicards in a loop
malloc Cabin

所以释放应该是相反的,即:

free Cabin
free Skicards in a loop
free Booking

你可以这样做:

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

booking 指针设置为 NULL,在调用函数中,在调用 removeBooking() 函数之后,或者作为替代方案,您可以传递预订指针的地址并在释放时取消引用它其他相关分配,并在 removeBooking() 的末尾设置 *booking = NULL.