2010-12-15 12 views
1

私はダブルフリーで走っていますが、どこで起きているのか分かりません。次のコードの目的は、リンクされたリストからPersonノードを削除することです。あなたは人を解放するとCダブルフリー問題

typedef struct person { 
    char *first ; 
    char *last ; 
    char *location ; 
    struct person *next_person ; 
} person ; 

struct person_list { 
    int num_persons ; 
    person *first_person ; 
} person_list ; 

extern struct person_list person_list ; 

void free_person(person *person) { 
    free(person->first); 
    person->first = NULL; 

    free(person->last); 
    person->last = NULL; 

    free(person->location); 
    person->location = NULL; 

    free(person); 
    person = NULL; 
} 

... 

    if (person_list.num_persons > 0) { 
     while (person_list.num_persons > 0) { 
      //Iterate to the end of the chain. 
      cur_person = person_list.first_person; 

      while (cur_person->next_person != NULL) { 
       cur_person = cur_person->next_person; 
      } 

      free_person(cur_person); 
      person_list.num_persons--; 
     } 
    } 

... 

答えて

5

は、あなたがNULLに、前の人のnext_personポインタを設定しないでください。したがって、解放されたメモリを指しています。そのため、ダブルフリーになっています。

無料にしたい人の前にいる人を追跡し、next_personポインタをNULLに設定する必要があります。あなたのループを記述するために

別のより効率的な方法は、同じエラーの対象ではありません、以下、次のようになります。

// Grab the first person 
    cur_person = person_list.first_person; 

    // Make sure there is someone to free 
    while (cur_person != NULL) { 
     // Keep track of who to free next 
     nxt_person = cur_person->next_person; 

     free_person(cur_person); 

     // Get the next person in line 
     cur_person = nxt_person; 
    } 

    // Didn't we just remove them all? Yes, we did. 
    person_list.num_persons = 0; 
    // Let's not forget to set that we have no one left 
    person_list.first_person = NULL; 
+0

しかし、free_personはその人物をNULLに設定します。なぜそれは働かないのですか? – Mike

+2

pmgが書いたように、関数内にはローカルコピーのみが設定されます。関数の外側でNULLに設定するか、参照(C++ではなくC++の機能)を渡す必要があります。 – Wolf

+0

意味があります。ありがとうございました! – Mike

1
void free_person(person *person) { 
    /* ... */ 
    free(person); 
    person = NULL; 
} 

これはNULLにローカルpersonを設定します。呼び出し元のルーチンに変更はありません。

1

free_person関数では、包含構造を解放するため、NULLへの代入は実際には必要ありません。それ以外の場合は、dangling pointerを防ぐ必要があります。

また、person = NULLは、戻り直後に失われた関数のローカルパラメータのみを割り当てます。