Reputation: 842
I am a beginner of C++, and still very confused if I correctly freed memories and removed possible dangling pointers. It was one of my school assignments in the past. There were so many students have the same problems, and no one else could help me. Please identify where I have problems.
==25334== Mismatched free() / delete / delete []
==25334== at 0x4006D21: free (vg_replace_malloc.c:446)
==25334== by 0x80492F2: HashTable::~HashTable() (Hash.c:115)
==25334== by 0x8049145: SymTab::~SymTab() (SymTab.h:9)
==25334== by 0x8048E9D: main (Driver.c:170)
==25334== Address 0x402c0b8 is 0 bytes inside a block of size 12 alloc'd
==25334== at 0x4007862: operator new(unsigned int) (vg_replace_malloc.c:292)
==25334== by 0x8048C73: main (Driver.c:143)
==25334==
==25334==
==25334== HEAP SUMMARY:
==25334== in use at exit: 18 bytes in 4 blocks
==25334== total heap usage: 10 allocs, 6 frees, 106 bytes allocated
==25334==
==25334== 18 bytes in 4 blocks are definitely lost in loss record 1 of 1
==25334== at 0x4007D58: malloc (vg_replace_malloc.c:270)
==25334== by 0x97E96F: strdup (strdup.c:43)
==25334== by 0x8048FDC: UCSDStudent::UCSDStudent(char*, long) (Driver.c:36)
==25334== by 0x8048C92: main (Driver.c:143)
==25334==
==25334== LEAK SUMMARY:
==25334== definitely lost: 18 bytes in 4 blocks
==25334== indirectly lost: 0 bytes in 0 blocks
==25334== possibly lost: 0 bytes in 0 blocks
==25334== still reachable: 0 bytes in 0 blocks
==25334== suppressed: 0 bytes in 0 blocks
==25334==
==25334== For counts of detected and suppressed errors, rerun with: -v
==25334== ERROR SUMMARY: 5 errors from 2 contexts (suppressed: 15 from 8)
Base.h
#ifndef BASE_H
#define BASE_H
#include <iostream>
using namespace std; /* C error */
/* TEMPLATE */
struct Base { /* C++ struct is public class, public methods */
/* PUBLIC SECTION */
/* virtual: candidates for redefinition */
virtual operator char * (void) {
return 0;
}
virtual operator long (void) { // hash function
return 0;
}
virtual long operator == (Base & base) {// isequal function
return *this == base;
}
Base (void) {} // new_element
virtual ~Base (void) {} // delete_element
virtual ostream & Write (ostream & stream) = 0;// write_element
};
#endif
Driver.c
class UCSDStudent : public Base { /* extends Base */
char * name;
long studentnum;
public:
UCSDStudent (char * nm, long sn) :
name (strdup (nm)), studentnum (sn) {} /* Initialization */
~UCSDStudent (void) { /* Destructor */
free (name);
}
Hash.c
/* HashTable constructor */
HashTable :: HashTable (int sz) : size (sz),
table_count(++counter), occupancy (0), table (new Base *[sz]),
probeCount (new int[sz])
HashTable :: ~HashTable (void)
{
/* call function to delete individual elements */
for(int index2 = 0; index2 < size; index2++)
{
if(table[index2] != NULL)
{
free(table[index2]);
table[index2] = NULL;
}
delete table[index2];
}
/*
* delete table itself
* Freed memory
*/
delete[] table;
delete[] probeCount;
/* pointed dangling ptr to NULL */
table = NULL;
probeCount = NULL;
} /* end: ~HashTable */
Upvotes: 1
Views: 1244
Reputation: 6771
The two Valgrind errors ("Mismatched free() / delete / delete []" and "18 bytes in 4 blocks are definitely lost") might be related.
In ~HashTable()
you call free(table[index2])
which probably means to destroy the UCSDStudent
objects (not sure, as you didn't post the whole program, esp. not the code which insert elements into HashTable
). I suppose you create UCSDStudent
objects with new
- and in that case, you also have to use the corresponding destruction method (in this case delete
instead of free()
). This is the cause for the first Valgrind error.
Furthermore, the free()
function will not call the object's destructor, while delete
will do that. This would explain why ~UCSDStudent()
is not called, causing your program to leak the memory for the student name. So using delete
instead of free()
in ~HashTable()
should solve both errors.
In general, you should try to stay with one way of memory allocation (either malloc()
/free()
or new/new[]/delete/delete[]
). And given that this is a C++ program, new
would be the appropriate choice. In the same vein, I'd advise you to remove the strdup()
and char*
stuff and switch to std::string
instead - this would remove another location where you might mix up free()
and delete
.
Upvotes: 2
Reputation: 1856
You're calling free
on memory that appears to have been declared using new
, which is the main error coming out of Valgrind there. You also appear to not be following the Rule of Three (although that doesn't appear to be your entire code there).
I would highly recommend you switch to using smart pointers such as std::shared_ptr / std::unique_ptr
, and use std::vector / std::array
to create containers.
Upvotes: 1
Reputation: 129314
Looks to me like you never call ~UCSDStudent
. Unfortunately, it's not possible to tell from the code you have posted, but the destructor itself looks good, so I expect the problem is that the destructor isn't being called.
Upvotes: 0