我释放节点的方式是否正确?

时间:2013-12-05 19:36:21

标签: c list pointers

所以我有这样的结构:

main1 -> main2 -> main3 -> .... ->main 13
  |        |        |               |
  v        v        v               v
node1    node1    node1            node1
  |        |        |               |
  v        v        v               v
node2    node2    node2            node2

所以每个main下面最多可以有5个节点,当然每个main下面的最后一个node5对于下一个down指针都是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;
}

所以我所做的就是我去每个主要部分并向下移动并释放每个节点,这是否按照我的方式正确完成?

5 个答案:

答案 0 :(得分:3)

如果你想从下到上释放()card_stack,可以采用递归的方式:

void freecardstack(card_ptr * acard)
{
  if ( acard-> next ) freecardstack( acard-> next ) ;
  free( acard) ;
}

然后在你的循环中:

freecardstack( current->card_stack ) ;
current-> card_stack= NULL ;

然而,堆(你获得内存的地方)并不关心你取消分配的顺序。只要你没有在free()之后引用内容,就可以从前到后释放卡片,所以你必须在执行免费之前将下一个指针存储在临时中:

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

答案 1 :(得分:1)

如果最后down指向NULL,则可以执行以下操作:

void post_order(card c)
{
  if (c) {
    post_order(c->down);
    free(c)
  }
}

答案 2 :(得分:1)

首先,除非你绝对必须,否则不要在你的代码中进行这样的分配和免费。我的经验,这从来没有发生在我身上,所以我在任何情况下都不会在我的任何代码中进行这样的分配。

您的问题的答案如下: 重新设计您的数据结构和逻辑。

如果代码变得繁琐,您可能没有仔细考虑数据的用途以及它们如何相互影响。

例如,对于上述情况,您可以为节点创建一个类/结构,为main创建一个类/结构: 1. Main将指向一个节点和下一个主节点。要释放所有主电源,首先主要呼叫免费连接节点和主节点。然后阻止等待调用返回,然后释放自己。如果main没有节点或main,则该例程将立即返回。 2.节点将只有指向连接节点的指针,实际上是一个单链表。释放节点时,递归地调用它的连接节点,直到命中NULL并返回。这将释放整个节点列表并返回上一级主。

答案 3 :(得分:1)

看起来你有很多代码基本上“免费卡,直到我们达到NULL”。没有理由你必须从头到尾释放它们。

while(current_card != NULL){
    card_ptr collector = current_card;
    current_card = current_card->down;
    free(collector);
}

此外,您需要设置current->card_stack = NULL,否则它将指向free'内存。

j未使用。消除它。

不是将list分配给current然后返回current,而是切断中间人并直接返回list

答案 4 :(得分:1)

如果您确实希望继续使用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!
  }