2017-03-31 17 views
0

因此,程序一切都很好,但我得到了一个非常恼人的内存泄漏。我坐在电脑前几个小时,可以弄明白。C内存泄漏,我根本找不到

我们有2个非常简单的结构,一个结构是一个双链表,一个是存储该双链表的散列表。

现在我将一个键和一个数据插入到双链表中,这里是函数。

void htable_insert(htable* ht, int key, int data) { 
    // TODO: Insert a new entry with the given key and data 
    // Overwrite the old data if the key already exists, duplicate keys are not allowed 
    ht_entry *new_node; 
    ht_entry *head; 
    ht_entry *it; 
    int sameKey; 
    int bucketPosition; 

    new_node = (ht_entry*)malloc(1*sizeof(ht_entry)); 
    bucketPosition = key % ht->size; 
    sameKey = 0; 

    for(it = ht->entries[bucketPosition]; it != NULL; it = it->next) 
    { 
     if(it->key == key) { 
     it->data = data; 
     sameKey = 1; 
     free(new_node); 
     new_node = NULL; 
     break; 

     } 
    } 

    if(!sameKey && new_node) { 
     head = ht->entries[bucketPosition]; 
     if (head == NULL) { 
     new_node->key = key; 
     new_node->data = data; 
     new_node->next = head; 
     new_node->prev = NULL; 
     ht->entries[bucketPosition] = new_node; 
     new_node = NULL; 

     } else { 
     new_node->key = key; 
     new_node->data = data; 
     new_node->next = head; 
     // new_node->prev = head; 
     head->prev = new_node; 
     head = new_node; 
     ht->entries[bucketPosition] = head; 

     } 
    } 
    // free(new_node); 
    new_node = NULL; 
    printf("%s\n %d", "INSERT:", key); 
    for(it = ht->entries[bucketPosition]; it != NULL; it = it->next){ 
     printf("it->key: %d\nit->data: %d\n", it->key, it->data); 
    } 


    printf("%s\n", "-------------------------------"); 


} 

这里是我的valgrind消息:

==10692== Memcheck, a memory error detector 
==10692== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==10692== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info 
==10692== Command: ./chain_hash_table.out 
==10692== 
==10692== 
==10692== HEAP SUMMARY: 
==10692==  in use at exit: 72 bytes in 3 blocks 
==10692== total heap usage: 10 allocs, 7 frees, 376 bytes allocated 
==10692== 
==10692== 24 bytes in 1 blocks are definitely lost in loss record 2 of 3 
==10692== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10692== by 0x4007EE: htable_insert (htable.c:53) 
==10692== by 0x400BD2: main (main.c:14) 
==10692== 
==10692== 48 (24 direct, 24 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3 
==10692== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10692== by 0x4007EE: htable_insert (htable.c:53) 
==10692== by 0x400C25: main (main.c:18) 
==10692== 
==10692== LEAK SUMMARY: 
==10692== definitely lost: 48 bytes in 2 blocks 
==10692== indirectly lost: 24 bytes in 1 blocks 
==10692==  possibly lost: 0 bytes in 0 blocks 
==10692== still reachable: 0 bytes in 0 blocks 
==10692==   suppressed: 0 bytes in 0 blocks 
==10692== 
==10692== For counts of detected and suppressed errors, rerun with: -v 
==10692== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) 

而且我知道它是什么,总是第一个表中插入,这就是为什么它在第一插入有后说,在线路主要(18)为休息没有泄漏。

谢谢你们的时间和帮助:)

+0

为什么你在for循环中有“break”? – paulsm4

+0

请发布完整的代码。 – Jay

+0

@Jay我无法发布完整的代码在公共领域,但如果你喜欢我可以通过消息发送给你。 – twistedhat

回答

-1

如果您在C程序mallocing空间,除非你在最后自由的一切,你将最终内存泄漏。

对于您当前的程序,我假设您最终没有正确释放。所以这个问题不在htable_insert函数中,而是在你的释放/清除函数中。

如果您将链接列表节点释放在您的htable_insert中,您将无法在其他程序中访问它们,并且会遇到段错误。

+2

更改“new_node = NULL;” on“if(new_node!= NULL)free(new_node); new_node = NULL;” –

0

检查循环中的break语句,它在第一次迭代 上中断,并且不释放该节点。

中断应放在for循环中。

+0

是啊......它没有改变一件事情,但thx的小错误,显然它进入if :) – twistedhat

+0

你是否在程序结束时释放内存。最终必须释放整个数据结构。 –