2016-04-07 8 views
0

Cの初心者として、私は無料で使うべきかどうかは分かりません。私は、リストの最後から要素を削除するpopメソッドに取り組んでいます。また、削除された要素の値も返す必要があります。ここでCでの二重リンクリストの実装のためのPopメソッドフリーで使う必要がありますか?

は私ListListNode構造体私のremove_from_back関数のコードHERESに

typedef struct ListNode { 
    struct ListNode *next; 
    struct ListNode *prev; 
    void *value; 
} ListNode; 

typedef struct List { 
    int count; 
    ListNode *first; 
    ListNode *last; 
} List; 

です。ノード典型的

void add_to_back(List *list, void *value) 
{ 
    ListNode *node = calloc(1, sizeof(ListNode)); 
    node->value = value; 

    if (list->first == NULL) { 
     list->first = node; 
     list->last = node; 
    } else { 
     list->last->next = node; 
     node->prev = list->last; 
     list->last = node; 
    } 

    list->count++; 
} 
+3

あなたはCと言いますが、['delete'](http://www.cplusplus.com/reference/new/operator%20delete [] /)はC++演算子です。あなたのノードが['malloc'](http://linux.die.net/man/3/malloc)で割り当てられていたら[' free'](http://linux.die.net/man/3/無料)を解放します。一般的には、ノードを割り当てた人に任せて、ノードを解放してください。それをあなたの機能の一部にしないでください。 – Jens

+0

削除はcに存在しません。多分あなたは自由()を意味するでしょうか? – Pemdas

+0

はい、ありがとうございました、私は質問を更新しました。 @ジェンズはそれを拡大できますか?ノードを削除する関数がある場合、削除するノードを解放する必要があるのはなぜですか? –

答えて

1

add_to_back()関数がノードのメモリを割り当てたため、remove_from_back()関数はノードのメモリを削除する必要があります。しかし、ノードが指すデータを解放すべきではありません。したがって:

void *remove_from_back(List *list) 
{ 
    void *result = NULL; 

    if (list->last == NULL) return result; 

    ListNode *dead = list->last;   // Added 
    result = list->last->value; 
    if (list->last->value == list->first->value) { 
     list->last = list->first = NULL;  
    } else { 
     list->last = list->last->prev; 
     list->last->next = NULL;   
    } 
    free(dead);        // Added 
    return result; 
} 

私はわずか2行追加しました。中間の行を変更していないので、元のコードにバグがあると、それらのバグも改訂されたコードにあります。 追加された行は、データがリストに追加されたときに割り当てられたノードのリークを防止します。

メモリを割り当てるときに、対応するfree()がどこで発生するかを知る必要があります。あなたがわからない場合は、どのように解放されるのかを決定し、解放メカニズムを実装する必要があります。時には、あなたはそれが問題ではないという決定をすることができます - プログラムはとにかく終了しようとしています。しかし、再利用可能なコードでは、この仮定を正当化することはほとんどできません。これはファイルのオープンとクローズのようなものです。クローズファイルを無視することはできますが、最終的にオープンファイルが多すぎると問題に陥ります。

0

ためのメモリを作成

void *remove_from_back(List *list) 
{ 
    void *result = NULL; 

    if (list->last == NULL) return result; 

    result = list->last->value; 
    if (list->last->value == list->first->value) { 
     list->last = list->first = NULL;  
    } else { 
     list->last = list->last->prev; 
     list->last->next = NULL;   
    } 
    return result; 
} 

add_to_back機能、ポップ方法は、データ構造から要素を削除して、それへのポインタを返すことになります。次に、値を抽出したり、要素に割り当てられたメモリを解放したりするなど、要素の操作を実行します。あなたの例では、典型的ではありませんが、あなたはおそらくメモリを漏らしています。ポップされているノードへの参照はすべて失われます。

ノードを解放する必要がある場合は、それを処理するコードを変更します。

if (list->last == list->first) 
{ 
    free (list->last); 
    list->last = list->first = NULL; 
} 
else 
{ 
    ListNode * temp = list->last; 
    list->last = list->last->prev; 
    list->last->next = NULL; 
    free (temp); 
} 
+0

ノードを適切に解放する方法の例を挙げることができますか?また、NULL値をデフレクレンジする場所もあります。 –

+0

私はもはや逆参照を見ません。私はある時点で編集が行われたと推測しています。 – Pemdas

0

あなたのmallocsを解放することをお勧めします。 Linuxで作業している場合は、valgrindを使ってメモリに何が起こっているかを確認してください。

valgrind Summary

私はvalgrindのとここに私のプログラムの出力を掲載しています。ご覧のように、私は6つのallocsを使用し、5を解放しました(あなたには:))。

また、私は1つのallocを解放しなかったので、100バイトを失ったことが分かります。

ここで、私たちのallocsを解放しないとどうなるでしょう。

関連する問題