C 释放节点的方式正确吗?
所以我有一个这样的结构:C 释放节点的方式正确吗?,c,list,pointers,C,List,Pointers,所以我有一个这样的结构: main1 -> main2 -> main3 -> .... ->main 13 | | | | v v v v node1 node1 node1 node1 | | | | v v v
main1 -> main2 -> main3 -> .... ->main 13
| | | |
v v v v
node1 node1 node1 node1
| | | |
v v v v
node2 node2 node2 node2
void post_order(card c)
{
if (c) {
post_order(c->down);
free(c)
}
}
所以我可以在每个main下有多达5个节点,当然每个main下的最后一个节点5的下一个向下指针为NULL
这是我的密码
//free stacks of cards
card_pos_ptr freeList(card_pos_ptr list){
int i, j;
int count = 1;
card_pos_ptr current = list;
card_ptr current_card = current->card_stack;
//traverse entire clock to free every single card
for(i=0;i<13;i++){
//reset the position of current card according to clock position
current_card = current->card_stack;
//get the numbers of cards in the stack to be freed
while(current_card->down != NULL){
count++;
current_card = current_card->down;
}
//free cards @ each stack depend on how many cards in there
card_pos_ptr current_pos = current;
if(count == 5){
free(current_pos->card_stack->down->down->down->down);
free(current_pos->card_stack->down->down->down);
free(current_pos->card_stack->down->down);
free(current_pos->card_stack->down);
free(current_pos->card_stack);
}
if(count == 4){
free(current_pos->card_stack->down->down->down);
free(current_pos->card_stack->down->down);
free(current_pos->card_stack->down);
free(current_pos->card_stack);
}else if(count == 3){
free(current_pos->card_stack->down->down);
free(current_pos->card_stack->down);
free(current_pos->card_stack);
}else if(count == 2){
free(current_pos->card_stack->down);
free(current_pos->card_stack);
}else{
free(current_pos->card_stack);
}
current = current->next_pos;
}
//change the pointer position back to A from K
current = list;
return current;
}
因此,我要做的是转到每个主节点并向下释放每个节点,这样做是否正确?如果您想从下到上释放卡栈,递归可能是一种方法:
void freecardstack(card_ptr * acard)
{
if ( acard-> next ) freecardstack( acard-> next ) ;
free( acard) ;
}
然后在你的循环中:
freecardstack( current->card_stack ) ;
current-> card_stack= NULL ;
然而,获得内存的堆并不真正关心释放的顺序。只要在释放后不引用内容,就可以从前到后释放卡片,因此在释放之前,必须将下一个指针存储在临时文件夹中:
{
card_ptr * tempcard ;
for ( current_card= current-> card_stack ; ( current_card ) ; current_card= tempcard )
{
tempcard= current_card-> next ;
free( current_card ) ;
}
current-> card_stack= NULL ;
}
如果最后一个down指向NULL,则可以执行以下操作:
main1 -> main2 -> main3 -> .... ->main 13
| | | |
v v v v
node1 node1 node1 node1
| | | |
v v v v
node2 node2 node2 node2
void post_order(card c)
{
if (c) {
post_order(c->down);
free(c)
}
}
首先,不要在代码中进行这样的分配和释放,除非你必须这样做。根据我的经验,这从未发生在我身上,因此我从未在任何情况下在我的任何代码中进行此类分配 你的问题的答案如下: 重新设计数据结构和逻辑 如果代码变得如此乏味,那么很可能您还没有充分考虑数据的用途以及它们之间的交互方式 例如,对于上述情况,您可以为node创建一个类/结构,为main创建一个类/结构: 1.Main将有指向一个节点和下一个Main的指针。要释放所有电源,请为连接的节点和主节点释放第一个主呼叫。然后,在释放自身之前,它阻塞等待调用返回。如果main没有节点或main,则该例程将立即返回。
2.节点将只有指向连接节点的指针,实际上是一个单链表。释放节点时,递归调用free到其连接的节点,直到命中NULL并返回。这将释放整个节点列表并返回到上层main。似乎您有大量代码基本上可以释放卡,直到我们达到空值为止。你没有理由把它们从下到上都放出来
while(current_card != NULL){
card_ptr collector = current_card;
current_card = current_card->down;
free(collector);
}
另外,您需要设置current->card_stack=NULL,否则它将指向空闲内存
j是未使用的。消除它
不要将列表分配给当前值,然后返回当前值,而要删掉中间人,直接返回列表。如果您想继续使用count变量,可以通过以下方法减少If-else链中的代码量:
switch(count){
default: // uh oh, more than 5 cards?
case 5:
free(current_pos->card_stack->down->down->down->down);
case 4:
free(current_pos->card_stack->down->down->down);
case 3:
free(current_pos->card_stack->down->down);
case 2:
free(current_pos->card_stack->down);
case 1:
free(current_pos->card_stack);
case 0:
current_pos->card_stack = NULL; // Prevent use after free!
}
是否有任何理由不只是返回列表;在函数结束时?您可能还想设置每个当前的\u pos->card\u stack=null。它将生成smame结果作为current=list,然后返回current right?我是说自从。。。当前从列表开始?我将使用递归。。。它看起来比开关或我愚蠢的大代码更优雅。。。谢谢你们。哇,比我的短多了,谢谢。我应该更多地考虑递归。current_pos->card_stack=NULL,或者你在释放bug后请求使用。我会将其更改为NULL,谢谢你,因为我会让所有主节点保持活动状态,以备下一轮使用。来吧,如果你想聪明一点,请一直使用fall-through开关语句。@woolstar先生,是的先生;