0

So everything is fine with the program but i get a very annoying memory leak. I am sitting in front of my computer for couple hours and can figure it out.

We have 2 struck very simple, one struct is a double linked list and one is a hash table that stores that double linked list.

Now i am inserting a key and a data into the double linked list here is the function.

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", "-------------------------------");


}

Here is my valgrind message:

==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)

And what i know it is always for first table insertion that is why it says at line main(18) for the rest after the first insertion there is no leaks.

Thank you guys for your time and help :)

twistedhat
  • 55
  • 10
  • Why do you have that "break" in your for loop??? – paulsm4 Mar 31 '17 at 17:59
  • Pls post the complete code. – Jay Mar 31 '17 at 18:17
  • @Jay i can't post the complete code on a public domain but if you like i can send you it via message. – twistedhat Mar 31 '17 at 18:19
  • Are you freeing the ht->entries properly? I think your leak stems from that. Can you post the free function? – Jay Mar 31 '17 at 18:20
  • you can find it here http://stackoverflow.com/questions/43125266/freeing-a-double-pointer-from-a-struct/43125587#43125587 – twistedhat Mar 31 '17 at 18:22
  • Not able to make out the reason of the leak with the available code. Looks like the problem is somewhere else. How many times are you calling htable_insert? I hope there is just one htable. – Jay Mar 31 '17 at 18:35
  • no it is only one table i am calling insert a lot but i notice that leaks only happen for the first hash insert... so if i do insert(ht, 33, 10) and if ht->entries[bucketpostion] is null, leak happens. – twistedhat Mar 31 '17 at 18:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139619/discussion-between-jay-and-twistedhat). – Jay Mar 31 '17 at 18:39
  • In the else block, you need to set new_node->prev to NULL, though I don't think that is anyway related to this problem. – Jay Mar 31 '17 at 18:50
  • BTW: IMHO it is not necessary to use a *doubly* linked list for hash chains. Do you ever *use* the `->prev` pointer? – wildplasser Apr 01 '17 at 15:43
  • Did it get solved at all? – Jay Apr 01 '17 at 16:48

2 Answers2

0

Check the break statement in the loop, it breaks on the first iteration and it does not deallocate the node.

The break should be placed inside the for loop.

-1

If you are mallocing space in a C program, unless you free everything at the end, you will end up with memory leaks.

For your current program, I'm assuming that you don't free correctly in the end. So the problem isn't within the htable_insert function, but rather within your freeing/cleanup functions.

If you free your linked list nodes in your htable_insert, you will not be able to access them in the rest of your program and you'll run into segfaults.