Question

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 */
Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top