在 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);
这是一个未定义的行为。不确定你想在这里完成什么,因为你的释放不会改变 nrOfPerson
或 ptrSkicard
。 free()
不改变指针。
请注意,您的函数按值传递点,因此您不能在函数外部更改指针。如果你需要,那么:
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
.
我构建了一个程序,其中包含多个结构。我们有一个名为 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);
这是一个未定义的行为。不确定你想在这里完成什么,因为你的释放不会改变 nrOfPerson
或 ptrSkicard
。 free()
不改变指针。
请注意,您的函数按值传递点,因此您不能在函数外部更改指针。如果你需要,那么:
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
.