I am writing a c++ Hashtable
Here is my destructor:
HashMap::~HashMap()
{
for (int i=0; i<cap; i++)
{
Node* ptr = Hashtable[i];
while (ptr!=NULL)
{
Node* delptr;
delptr=ptr;
ptr=ptr->next;
delete delptr;
}
}
delete [] Hashtable;
}
My add function:
void HashMap::add(const std::string& key, const std::string& value)
{
int index = hashfunction(key)%cap;;
Node* ptr=Hashtable[index];
Node* newnode=new Node;
if (contains(key)==false)
{
if (ptr == nullptr)
{
newnode->key=key;
newnode->value=value;
newnode->next=NULL;
Hashtable[index]=newnode;
}
else
{
newnode->key=key;
newnode->value=value;
newnode->next=NULL;
while(ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->next=newnode;
}}}
But I keeps getting memory leak error
==13676==
==13676== HEAP SUMMARY:
==13676== in use at exit: 12 bytes in 1 blocks
==13676== total heap usage: 42 allocs, 41 frees, 669 bytes allocated
==13676==
==13676== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==13676== at 0x402BE94: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13676== by 0x804BF8D: HashMap::add(std::string const&, std::string const&) (HashMap.cpp:112)
==13676== by 0x804AFD2: main (main.cpp:18)
==13676==
==13676== LEAK SUMMARY:
==13676== definitely lost: 12 bytes in 1 blocks
==13676== indirectly lost: 0 bytes in 0 blocks
==13676== possibly lost: 0 bytes in 0 blocks
==13676== still reachable: 0 bytes in 0 blocks
==13676== suppressed: 0 bytes in 0 blocks
==13676==
==13676== For counts of detected and suppressed errors, rerun with: -v
==13676== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
The line its indicates is Node* newnode=new Node; because I use "new" here, this newnode needed to be deallocated, but the destructor only deallocate content in Hashtable. If I don't use "newnode", I will have null-pointer access error because nullptr does not have access to Node (Node is a struct has key and value), I can only let the pointer points to a "newnode."However, adding extra "delete newnode" makes me getting more than 20 errors. I really need you help!
If I write this, I still get an error
if (contains(key)==false)
{
if (ptr == nullptr)
{
Node* newnode=new Node;
newnode->key=key;
newnode->value=value;
newnode->next=NULL;
Hashtable[index]=newnode;
}
else
{
Node* newnode=new Node;
newnode->key=key;
newnode->value=value;
newnode->next=NULL;
while(ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->next=newnode;
}}
This line
creates a local newnode pointer which will go out of scope after the add function exits. This will leak memory allocated by new.
Simply declare the newnode and then after the if statement allocate the new Node. The way your code is right now the newnode can be allocated , the if statement goes wrong and the newnode stays in memory never used.
The problem is that you are doing this:
What you need to do is do the conditional BEFORE the new.
---- Edit ----
What ValGrind is telling you is that your code allocated a pointer at HashMap.cpp line 112, but it never stored the address -- this is what happens in your code when someone calls the add function with a key for which "contains(key)" does not return false. You don't store the pointer, and so the Node you allocated is left allocated but your code is not tracking it -> it's a leak.