Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 释放节点的方式正确吗?_C_List_Pointers - Fatal编程技术网

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先生,是的先生;