【问题标题】:Free a linked list释放一个链表
【发布时间】:2015-09-27 13:52:37
【问题描述】:

我无法正确释放我的链表。我真的不知道,如何用头部和电流来制作它......

typedef struct list{
   int info;
   struct list *link;
} Node;

Node *_getnode (){
    return((Node *) malloc (sizeof (Node)));
}

int main() {

    Node *s = _getnode();
    s -> link = NULL;
    Node *t = s;
    int c;

    while (1) {
        printf("\n\t Enter number : ");
        scanf ("%d", &s -> info);   

        printf ("\n\t Continue? ");
        __fpurge (stdin);
        c = getchar ();

        if (c == 'N' || c == 'n'){
            s -> link = NULL;
            break;
        }

        s -> link = _getnode ();
        s = s -> link;
    }

    s = t;

    free(s);
    free(t);

    putchar('\n');
    return (0);
}

当我只输入一个数字时,正如 valgrind 所说,没有内存泄漏。但除此之外还有。我明白,我必须释放的不仅仅是第一个节点,但我不知道如何。

【问题讨论】:

  • 使用__fpurge 不是一个好主意 - 它不可移植等。双下划线是一种放弃
  • 不要转换malloc()的返回值。您需要释放每个节点。

标签: c memory-leaks linked-list valgrind free


【解决方案1】:

首先是线条

free(s);
free(t);

是多余的,因为您已经在上一行中分配了s = t;

发生内存泄漏是因为您只在头指针上使用free,而不是链表中的所有节点。所以理想情况下,您应该遍历所有节点并释放分配给每个节点的内存,您的代码应该如下所示:

while(s != NULL)
{
     t = s->link;
     free(s);
     s = t;
}

【讨论】:

    【解决方案2】:

    这样试试

    void free_list(Node *head)
    {
        Node *s;
        Node *n;
        if (head == NULL) /* passing `NULL' should be ok */
            return;
        for (s = head ; s != NULL ; s = n)
        {
            n = s->link;
            free(s);
        }
     }
    

    您会发现创建列表的方式存在明显缺陷。

    【讨论】:

      【解决方案3】:

      首先,请初始化节点,以便程序能够正确判断列表的结尾。

      Node *_getnode (){
          Node* buffer = malloc (sizeof (Node));
          if (buffer == NULL) exit(1);
          buffer->info = 0; /* not important */
          buffer->link = NULL; /* this is important */
          return buffer;
      }
      

      然后,一一释放节点。

      void free_nodes (Node* head){
          while(head != NULL){
              Node* next = head->link;
              free(head);
              head = next;
          }
      }
      

      未经测试,将t 传递给此free_nodes 应该可以工作。

      【讨论】:

      • 感谢您的建议。已编辑。
      猜你喜欢
      • 2021-04-08
      • 1970-01-01
      • 2019-08-18
      • 2023-03-09
      • 1970-01-01
      • 2021-07-07
      • 2013-10-30
      • 2019-07-08
      • 2021-09-24
      相关资源
      最近更新 更多