内存泄漏-C中的单链表

时间:2019-05-08 17:17:12

标签: c linked-list valgrind singly-linked-list

我实现了此简单代码,以在C中实现单链接列表。我只是为此代码发布了另一个问题(link)。 我将代码放在相同的位置,以便您无需更改页面即可看到它。这是代码:

列表节点的结构:

struct hash_table_key_list_node_s {
  char *key;
  struct hash_table_key_list_node_s* next;
};

typedef struct hash_table_key_list_node_s hash_table_key_list_node_t;
typedef hash_table_key_list_node_t* hash_table_key_list_t;

功能代码:

hash_table_key_list_t hash_table_keys(hash_table_t hash_table) {

  hash_table_key_list_t list, tail, p;
  list = tail = NULL;

  if ( hash_table != NULL && hash_table->slots != NULL ) {

    size_t index = 0;
    while ( index < hash_table->capacity ) {

      hash_table_list_node_t *node = hash_table->slots[index].head;
      while ( node != NULL ) {

        p = malloc(sizeof(hash_table_key_list_node_t));
        p->key = malloc((strlen(node->key) + 2) * sizeof(char));
        if ( p->key == NULL ) {
          perror("Unable to allocate a key\n");
          abort();  
        }

        strcpy(p->key, node->key);

        if ( node != NULL ) {
          list = tail = p;
        }
        else { 
          tail->next = p;
          tail = p;
        }

        node = node->next;
      }

      index++;
    }
  }

  return list; 
}

销毁列表功能

void destroy_key_list(hash_table_key_list_t key_list) {

  hash_table_key_list_node_t *current = NULL;

  if ( key_list == NULL ) return;

  while ( key_list != NULL ) {
    current = key_list;
    free(current->key);
    free(current);

    key_list = key_list->next;
  }

  free(key_list);
}

我有两个我不明白的问题:

  • 为什么使用返回到函数的列表后,列表不再包含节点?是列表类型吗?
  • 为什么它会导致我丧气?在增加free变量之前,我尝试在node变量上调用index函数,但没有任何变化。

这是一次调用函数后valgrind的输出:

==10757== HEAP SUMMARY:
==10757==     in use at exit: 15,840 bytes in 660 blocks
==10757==   total heap usage: 1,329 allocs, 669 frees, 123,642 bytes allocated
==10757== 
==10757== 5,264 bytes in 329 blocks are indirectly lost in loss record 1 of 3
==10757==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10757==    by 0x10B93E: hash_table_keys (in /media/psf/bioinformatics-assignment-1/app/main)
==10757==    by 0x109B27: main (in /media/psf/bioinformatics-assignment-1/app/main)
==10757== 
==10757== 10,560 bytes in 330 blocks are indirectly lost in loss record 2 of 3
==10757==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10757==    by 0x10B975: hash_table_keys (in /media/psf/bioinformatics-assignment-1/app/main)
==10757==    by 0x109B27: main (in /media/psf/bioinformatics-assignment-1/app/main)
==10757== 
==10757== 15,840 (16 direct, 15,824 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==10757==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10757==    by 0x10B93E: hash_table_keys (in /media/psf/bioinformatics-assignment-1/app/main)
==10757==    by 0x109B27: main (in /media/psf/bioinformatics-assignment-1/app/main)

在这里您可以找到所有的源文件和头文件:

1 个答案:

答案 0 :(得分:2)

请注意:

while ( key_list != NULL ) {
    current = key_list; // current is now a copy of key_list (a copy of the pointer)
    free(current->key);
    free(current);      // here you free current and hence key_list

    key_list = key_list->next; // here you are referring to key_list, just freed above
  }

尝试以下方法:

while ( key_list != NULL ) {
    current = key_list; 
    key_list = key_list->next; 
    free(current->key);
    free(current);      
  }

您的代码中可能还存在其他错误,但这只是一个错误。