2

ここ数日、私は自分の c\c++ スキルに取り組んでいます。私は自分のデータ構造の本を読んでいて、二重連結リスト プログラムを実装しない理由を考えました。プログラムを書きました。意外にもうまくいきますが、正しく書いたかどうかはわかりません。割り当てたメモリを解放する方法がわかりません。この人たちで私を助けてください。

また、この「while(linkNode!=0)」について説明していただける方がいらっしゃいましたら、よろしくお願いいたします。

#include<stdio.h>
#include<malloc.h>

struct node
{
    int x;
    struct node * next;
    struct node * prev;
};

struct head
{
    unsigned int count;
    struct node * hd;
    struct node * tl;

};


void main()
{
    int i =0;

    struct node * linkNode;
    struct head *hdd;

    hdd = (head *)malloc(sizeof(head));

    linkNode = (node *) malloc(sizeof(node));
    hdd->count = 1;
    hdd->hd = linkNode;
    linkNode->prev = 0;
    linkNode->next = 0;
    linkNode->x = 0;


    for(;i<10;i++)
    {
        linkNode->next = (node *) malloc(sizeof(node));
        linkNode->next->prev = linkNode;
        linkNode = linkNode->next;
        linkNode->next = 0;
        linkNode->x = i;
        hdd->count+=1;
        hdd->tl = linkNode;

    }

    linkNode = hdd->hd;
    printf("priniting in next direction\n");
    while(linkNode!=0)
    {
        printf("%d\n",linkNode->x);
        linkNode = linkNode->next;
    }


    linkNode = hdd->tl;
    printf("priniting in prev direction\n");
    while(linkNode!=0)
    {
        printf("%d\n",linkNode->x);
        linkNode = linkNode->prev;
    }

    linkNode = hdd->hd;
    while(linkNode!=0)
    {
        free(linkNode->prev);
        linkNode = linkNode->next;

    }

    free(hdd);


}
4

2 に答える 2

3

リンクされたリストは次のようになります。

+------+----+----+
| Head | hd | tl | ---------->--------
+------+----+----+                    \
         |               ---->------   |           NULL
         |             /            \  |             |
     +------+-----+------+------+   +------+-----+------+------+
     | Node | x=0 | next | prev |   | Node | x=1 | next | prev |
     +------+-----+------+------+   +------+-----+------+------+
         |                  |                             |
          \                NULL                          /
           -----------------------<----------------------

(2 つのノードに簡略化しました)。

さて、このコードが何をするかを書き出すことができます:

linkNode = hdd->hd;
while(linkNode!=0) {
    free(linkNode->prev);
    linkNode = linkNode->next;
}
  1. linkNode = hdd->hdlinkNode最初の節を指す葉
  2. (linkNode!=0)は true (最初のノードは NULL ではない) であるため、while ループに入ります。
  3. free(linkNode->prev)free(NULL)それ以降の呼び出しhdd->hd->prev == NULL(このように最初のノードを明示的に設定します)。これは問題ありませんが、何もしません。
  4. linkNode = linkNode->nextlinkNode最後のノードを指す葉
  5. linkNode!=0はまだ真です (最後のノードも NULL ではありません)。
  6. free(linkNode->prev)前のノード (最初のノード) を解放します
  7. linkNode = linkNode->nextlinkNode == NULL
  8. linkNode!=0現在は false であるため、ループは終了します。

そのため、最後のノードを除くすべてを解放しました。ノードのprevメンバーはそのノードを指していないため、呼び出しfree(linkNode->prev)によって解放されることはありません。ただし、 を介して解放することはできhdd->tlます。

于 2013-01-21T18:42:09.410 に答える
1

リストの末尾から逆の順序で、リンクされたリストのノードに割り当てられたメモリを既に解放しています。この行はこれを行っています。

free(linkNode->prev);

プログラムにメモリ リークがあります。リストの最後のノードは解放されません。

含めるだけ

free(linkNode);

hdd を解放する前に。

説明:

while(linkNode!=0)

これは、NULLポインターを逆参照していることを確認するためです。NULL ポインターを逆参照すると、undefined behaviours.

これらは逆参照操作です

linkNode->x
linkNode->prev
于 2013-01-21T17:56:24.103 に答える