web-dev-qa-db-ja.com

LinkedList-mallocを使用して割り当てられたメモリを解放する方法

以下のように、Singly Linkedリストを作成するための非常に単純なCコードがあります。このコードでは、mallocを使用して各ノードにメモリを動的に割り当てます。コードの最後に、割り当てられた各ノードのメモリを解放したいのですが、どうすればいいのか疑問に思っていました-最初にヘッドノードから開始して解放すると、後続のノードへのポインタが失われ、メモリリークが発生します。

他の方法は、ヘッドノードから開始し、別のポインター配列にノードポインターを格納し続け、ノードポインターを格納しながらテールポインターまでリストを走査し、テールノードに到達したら、それを他の配列にも格納しますポインターを返し、ヘッドノードが解放されるまで、その配列インデックスから逆方向に解放を開始します。

それが私がやろうとしていることを達成する唯一の方法ですか?

2番目のバッファーを使用したくない場合、どうすればよいですか。

#include "stdio.h"
#include "stdlib.h"

struct lnk_lst 
{
   int val;
   struct lnk_lst * next;
};

typedef struct lnk_lst item;


main()
{
   item * curr, * head;
   int i,desired_value;

   head = NULL;

   for(i=1;i<=10;i++) 
   {
      curr = (item *)malloc(sizeof(item));
      curr->val = i;
      curr->next  = head;
      head = curr;
   }

   curr = head;


   while(curr) {
      printf("%d\n", curr->val);
      curr = curr->next;
   }

  //How to free the memory for the nodes in this list?
   for(i=1;i<=10;i++)
   {
       free()//?? What logic here
   }


}
32
goldenmean

通常の方法は(最初に擬似コードを使用する)です。

node = head              # start at the head.
while node != null:      # traverse entire list.
    temp = node          # save node pointer.
    node = node.next     # advance to next.
    free temp            # free the saved one.
head = null              # finally, mark as empty list.

基本的な考え方は、別の変数で解放するノードを記憶し、解放する前に次のノードに進むことです。

提案するリスト全体ではなく、一度にoneノードのみを覚えておく必要があります。

コードに追加する必要があるものに関しては、削除中にheadを継続的に更新するリストヘッド(本来の意味)として使用し、currを使用してアイテムを保存できます。 '現在削除しています:

while ((curr = head) != NULL) { // set curr to head, stop if list empty.
    head = head->next;          // advance head to next element.
    free (curr);                // delete saved pointer.
}

これは、一部の操作でCの「速記」を利用するという理由だけで、上記の擬似コードよりも少し短くなっています。

65
paxdiablo

私はこのようなものを使用します:

for (p = curr; NULL != p; p = next) {
    next = p->next;
    free(p);
}
9
cnicutar

無料のコードは次のようになります。

lnk_lst temp = null;
while(head) 
{
  temp = head->next;
  free(head);
  head = temp;
}

また、私はあなたのmallocの後に、おそらくmemが正常に割り当てられたかどうかをチェックしたいので追加したいと思います。

if(curr)
2
Baz1nga

上記と同じロジックを使用してリストを走査します。 curr-> nextポインターをどこかに保存し、curr構造体を解放し、保存したcurr-> nextポインターでcurrを割り当てます。

1
duedl0r