I have written some code that stores values inside a array of arrays. I am releasing the memory in my release method but Valgrind still reports the following:
==640==
==640== HEAP SUMMARY:
==640== in use at exit: 6,094 bytes in 33 blocks
==640== total heap usage: 12,040 allocs, 12,007 frees, 24,146,162 bytes allocated
==640==
==640== LEAK SUMMARY:
==640== definitely lost: 0 bytes in 0 blocks
==640== indirectly lost: 0 bytes in 0 blocks
==640== possibly lost: 0 bytes in 0 blocks
==640== still reachable: 6,094 bytes in 33 blocks
==640== suppressed: 0 bytes in 0 blocks
==640== Rerun with --leak-check=full to see details of leaked memory
==640==
==640== For counts of detected and suppressed errors, rerun with: -v
==640== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
My code is as follows. I first allocate a heap and insert keys in 1 array. Then I have a 2D array (array within arrays) to hold the keys. After inserting, I would like to release the memory.
I cant find where this memory is still active. Can someone please help? Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct hashmap
{
int** value;
int* key;
int keylength;
int x;
int y;
};
typedef struct hashmap hashmap;
/*
hashmap* hm_initialize();
Dynamically allocates a new hashmap and returns a pointer to it.
*/
hashmap* hm_initialize()
{
hashmap *hm = malloc(sizeof(hashmap));
hm->value = (int**)malloc(sizeof(int*));
hm->value[0] = (int*)malloc(sizeof(int));
hm->value[0][0] = -999999991;
hm->key = (int*)malloc(sizeof(int));
hm->key[0] = -999999991;
hm->keylength = 1;
hm->x = 1;
hm->y = 1;
return hm;
};
/*
void hm_release(struct hashmap*);
Releases all memory allocated for the given hashmap.
*/
void hm_release(struct hashmap* hm)
{
free(hm->key);
for(int x = 0; x<hm->x;x++)
free(hm->value[x]);
free(hm->value);
free(hm);
}
/*
void hm_insert(struct hashmap* hm, int key, int value);
Inserts the key-value pair to the hashmap.
*/
void hm_insert(struct hashmap* hm, int key, int value)
{
int flagkey = 0;
int flagvalue = 0;
int flaglocationkey;
int flaglocationvalue;
int valueexists = 0;
int counter1 = 0;
for(int x = 0;x<hm->keylength;x++) {
if(hm->key[x] == key) { //Old Key Exists and is Active
flagkey = 1;
flaglocationvalue = x;
}
}
if(flagkey == 0) {
hm->key = realloc(hm->key,(hm->keylength+1)*sizeof(int));
hm->key[hm->keylength-1] = key;
hm->key[hm->keylength] = -999999991;
hm->keylength = hm->keylength + 1;
hm->value = (int**)realloc(hm->value,(hm->x+1)*sizeof(int*));
hm->value[hm->x] = (int*)malloc(sizeof(int));
hm->value[hm->x][0] = -999999991;
hm->value[hm->x-1] = (int*)realloc(hm->value[hm->x-1],2*sizeof(int));
hm->value[hm->x-1][1] = -999999991;
hm->value[hm->x-1][0] = value;
hm->x++;
}
if(flagkey == 1) {
printf("FOUND KEY \n");
printf("CONTENTS OF VAL1: %d \n", hm->value[flaglocationvalue][0]);
while((hm->value[flaglocationvalue][counter1]) != -999999991) {
if(hm->value[flaglocationvalue][counter1] == value) {
printf("TRUE");
valueexists = 1;
}
counter1++;
}
printf("CONTENTS OF VAL2: %d \n", hm->value[flaglocationvalue][counter1]);
printf("LENGTH %d \n", counter1);
if(valueexists == 0) {
hm->value[flaglocationvalue] = (int*)realloc((hm->value[flaglocationvalue]),(counter1+2)*sizeof(int));
hm->value[flaglocationvalue][counter1] = value;
hm->value[flaglocationvalue][counter1+1] = -999999991;
}
}
}
The Valgrind output you’re posting indicates that no memory leaks were detected:
The fourth line (below) does not mean that you leaked memory. It simply means that you did not free all of your memory before you exited. This does not constitute a memory leak, as the operating system implicitly frees all memory allocated by your program when you exit.
If you are trying to test your hashmap to make sure that it frees all memory on exit, you may have forgotten to call your
hm_releasefunction before exiting.