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>
/*
Note that this hashmap is required to be a multimap: that is, same
key can be associated to multiple values simultaneously. However,
the same key can be associated to the same value at most once. That is,
if you insert the key-value pairs (1,2), (1,5) and (1,2) to the map,
the key 1 has two associated values, 2 and 5.
*/
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)
{
// printf("KEY: %d , Value: %d \n", key, 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++)
{
//printf("LOOP: %d \n");
if(hm->key[x] == key)
{
//Old Key Exists and is Active
flagkey = 1;
flaglocationvalue = x;
}
}
//printf("CONTENTS: ");
//int counter1 = 0;
//while(hm->key[counter1] != -99999)
//{
// printf(" %d ", hm->key[counter1]);
// counter1++;
//}
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;
}
}
}
/*
Returns the count of how many values the given key is currently
associated with.
int hm_count(struct hashmap* hm, int key);
*/
int hm_count(struct hashmap* hm, int key)
{
int counter1 = 0;
int flaglocationvalue;
for(int x = 0;x<hm->keylength;x++)
{
if(hm->key[x] == key)
{
//Old Key Exists and is Active
flaglocationvalue = x;
printf("Location: %d \n", flaglocationvalue);
printf("Location: %d \n", hm->value[flaglocationvalue][1]);
break;
}
}
while((hm->value[flaglocationvalue][counter1]) != -999999991)
{
counter1++;
printf("ELEMENTS: %d ", counter1);
}
return counter1;
}
/*
Removes the association of key and value from the hashmap. If there
is no such association present, does nothing.
*/
void hm_remove(struct hashmap* hm, int key, int value)
{
}
/*
void hm_get(struct hashmap* hm, int key, int* arr);
Collects all values that are currently associated with the given
key into the array arr. You can assume that arr contains enough
room for all these keys when this function is called.
*/
void hm_get(struct hashmap* hm, int key, int* arr)
{
int counter1 = 0;
int flaglocationvalue;
for(int x = 0;x<hm->keylength;x++)
{
if(hm->key[x] == key)
{
//Old Key Exists and is Active
flaglocationvalue = x;
break;
}
}
while((hm->value[flaglocationvalue][counter1]) != -999999991)
{
arr[counter1] = (hm->value[flaglocationvalue][counter1]);
counter1++;
}
}