1

リンクされたリスト全体を解放するためのコードは次のとおりです

void free_list(RecordType *list)
{
   RecordType *tempNode;        /* temporary Node to hold on the value of previous node */

   while(list != NULL)          /* as long as the listnode doesn't point to null */
   {
       tempNode = list;         /* let tempNode be listNode in order to free the node */
       list = list->next;       /* let list be the next list (iteration) */
       free(tempNode);          /* free the node! */
   }
}

このコード自体は正常に動作していると思いますが (?)、確認方法がわかりません。私は理論を適用しただけです(たとえば、フリーの数=マロックの数にする必要があります)

そこで、気になる質問をいくつか...

  1. この方法は機能しますか?
  2. tempNode を malloc する必要がありますか?
  3. while ループの前に tempNode を初期化しました...しかし、解放した後も tempNode は引き続き機能します...その部分は実際にはわかりません

私が使用した理論:

  1. free() の数 == malloc() の数
  2. 現在のノードを保持するための一時ノードが必要です
  3. 現在のノードを次のノードと等しくする
  4. 一時ノードを使用して現在のノードを解放する

私の理論が間違っているように聞こえる場合は、説明してください!

ありがとう!

4

3 に答える 3

1

この方法は確かに機能しますが、ingmallocの前に dを実行する必要があります。freeそれ以外の場合は、未定義の動作です。

以前にdされたmalloc() tempNode場合にのみ必要はありません。listmalloc()

3 番目の部分は未定義の動作です。free()データがまだ存在している可能性がありますが、上書きのフラグが立てられた後。free()ノードがdになると、そのノードに依存することはできません

于 2013-02-28T09:31:09.893 に答える
0

コードをチェックする最良の方法は、デバッガーによるインタラクティブなトレースです。Linux 上の KDevelop の Gdb または MS Windows 上の MS Visual Studio のデバッガーは完璧です。このデモンストレーションでは後者を使用します。

このコードは、3 つの関数で整数の一方向リストを定義します。ListPush() は整数をリストに追加し、ListPrint() はリストの内容を表示し、ListDestroy() はリストを破棄します。main() では、3 つの整数をリストに挿入し、それらを出力してリストを破棄します。

#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct Node NODE, *PNODE;
typedef struct Node {
    int item;
    PNODE next;
};
PNODE ListPush(PNODE head, int item) {
    PNODE p;
    PNODE n = (PNODE) malloc(sizeof(NODE));
    if ( !n ) exit(1);
    n->next = 0;
    n->item = item;

    if (!head) {
        head = n;
    }
    else {
        for ( p=head; p->next != 0; p=p->next );
        p->next = n;    
    }
    return head;
}

void ListPrint(PNODE head) {
    PNODE p;
    printf("List contents:\n\n");
    for (p=head; p!=0; p=p->next) {
        printf("%d ", p->item ); 
    }
}

void ListDestroy( PNODE head ) {
    PNODE n, c = head;
    if ( !head ) return; 
    do {
        n = c->next;
        free(c);
        c = n;
    } while (c );

}

int main() {
    int i;
    int a[3] = {1,2,3};
    PNODE head = 0;
    for ( i = 0; i<3; ++i ) {
        head = ListPush(head, a[i]);
    }
    ListPrint(head);
    ListDestroy(head);
    return 0;
}

添付の 3 つの画像は、プログラム (MSVS2012 デバッガー) の 2 つの段階を示しています。

1 つ目は、for() サイクルが終了した後の関連するローカル変数の状態を示しています。head 変数を見て、ツリーを進めます。それぞれ整数 1、2、3 の 3 つのノードとその内容を確認できます。

2 番目の画像は、最初に free() を呼び出した後の ListDestroy() 内の変数を示しています。head が解放されたメモリ (赤い円) を指し、変数 c のポインターが次のループで破棄される次のノードを指していることがわかります。

3プッシュ後

free() への最初の呼び出しの後

于 2013-02-28T10:28:03.733 に答える