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

时间:2018-02-15 07:46:41

标签: c pointers memory-management struct free

我已经构建了一个程序,里面有几个结构。我们有一个名为Booking的“基础”结构,它将包含在度假地点预订所需的所有信息。它看起来像这样:

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;

预订还包含2个其他结构,一组人员最多可容纳8人,可以预订,还有一个小屋结构。 这两个看起来像这样:

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

4 个答案:

答案 0 :(得分:4)

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

Person arrPerson[MAX_GUEST];

Booking结构的组成部分,不应分配或解除分配 - 这些将使用Booking结构进行分配/取消分配。

但是我们保留的结构只是一个指针,即:

Skicard *ptrSkicard;

Cabin *cabin;

应该被分配和解除分配。

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

malloc Booking
malloc Skicards in a loop
malloc Cabin

所以解除分配应该是相反的,即:

free Cabin
free Skicards in a loop
free Booking

答案 1 :(得分:1)

你可以这样做:

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

的末尾

答案 2 :(得分:0)

您释放了 $insertRow = " INSERT INTO TABLE2 ( Name, Company, ProductName, Status, cron_modified_date) VALUES "; foreach ($getAllRows as $getRow) { $insertRow.="(".$GLOBALS['db_ab']->quote($getRow['Name']).", ".$GLOBALS['db_ab']->quote($getRow['Company']).", ".$GLOBALS['db_ab']->quote($getRow['ProductName']).", ".$getRow['Status'].", ".$GLOBALS['db_ab']->quote($getRow['created_date'])."),"; } $insertRow=rtrim($insertRow,','); // Remove last ',' $insertRow .= " ON DUPLICATE KEY UPDATE count = (count + 1) , cron_modified_date = '".$getRow['created_date']."'" ; $GLOBALS['db_ab']->execRaw( $insertRow ) ; $GLOBALS['db_ab']->queryString = null; $getRow = null; $insertRow = null; $GLOBALS['db_ab']->close() ; (由int i=0; long dataLen = dr.GetInt64(i++); if (dataLen > 0) { Data = new byte[dataLen]; dr.GetBytes(i++, 0, Data, 0, (int)dataLen); } 指出)占用的内存,然后您尝试访问它。

Booking

这是一种未定义的行为。不确定您要在此处完成什么,因为您的释放不会更改bookingfree(booking); printf("%d", booking->nrOfPerson); nrOfPerson不会改变指针。

请注意,您的函数会逐点传递,因此您无法在其外部更改指针。如果你需要,那么:

ptrSkicard

答案 3 :(得分:0)

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

如果您要免费预订(结构),那么您可以像上面那样设置 一旦检查了。谢谢