I was writing a generic Hashtable library but I keep getting problems while I use functions like the lookup(). The expected output should be:
result = thirteen
result = thirteen
result = thirteen
but I get:
result = thirteen
and then it crashes. This problem seems to appear when I call the lookup() function more then one time, in fact if I call lookup() one time the code runs without any problem.
Each time I call the lookup() function, it creates a new HashMap, but I can't see any correlation between having more HashMaps and the problem. I tried to solve the problem using a free() method between each lookup() function, but the problem kept on appearing.
This is a portion of the original code:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
typedef struct _Association Association;
typedef struct _HashMap HashMap;
typedef int (*HashMapCmp)(void*, void*);
/*
Hash Map
*/
struct _HashMap{
Association** array;
int number_of_rows;
int number_of_elements;
HashMapCmp cmp_key;
};
/*
element of the linked Hash Map
*/
struct _Association{
void* key;
void* value;
struct _Association* next;
};
/*
hash function
*/
unsigned int hash(HashMap* map, void* key){
unsigned int hash_value = 0;
hash_value = (*(int*)key * 1500) % map->number_of_rows;
return hash_value;
}
/*
inits a new Hash Map
*/
HashMap* HashMap_new(int table_size, HashMapCmp cmp_key){
HashMap* result = (HashMap*) malloc(sizeof(HashMap));
result->number_of_rows = table_size;
result->array = (Association**) malloc(sizeof(Association*) * result->number_of_rows);
result->number_of_elements = 0;
result->cmp_key = cmp_key;
for(int i = 0; i < result->number_of_rows; i++){
result->array[i] = malloc(sizeof(Association*));
result->array[i] = NULL;
}
return result;
}
/*
inserts a new association in my Hash Map
*/
bool HashMap_insert(HashMap* map, void* key, void* value){
if(map == NULL)
return false;
else{
int index = hash(map, key);
Association* as = malloc(sizeof(Association*));
as->key = key;
as->value = value;
as->next = map->array[index];
map->array[index] = as;
map->number_of_elements++;
return true;
}
}
/*
returns the value of the key passed by parameter
*/
void* HashMap_lookup(HashMap* map, void* key){
int index = hash(map, key);
Association* tmp = map->array[index];
while(tmp != NULL && map->cmp_key(tmp->key,key) != 0){
tmp = tmp->next;
}
return tmp->value;
}
/*
**************************************
tests methods
*/
/*
int pointer (key)
*/
int* int_new(int n) {
int* result = (int*) malloc(sizeof(int));
*result = n;
return result;
}
/*
char* pointer (value)
*/
char** string_new(char* s) {
char** result = (char**) malloc(sizeof(char*)*20);
*result = s;
return result;
}
/*
Integers comparator -> obj1>obj2 = 1, obj1<obj2 = -1, obj1=obj2 = 0
*/
static int compare_ints(int* obj1, int* obj2) {
return *obj1 - *obj2;
}
/*
creation of a 5 elements, high 4, HashMap
*/
HashMap* create_five_elements_hash_map(){
HashMap* map = HashMap_new(4, (HashMapCmp) compare_ints);
HashMap_insert(map, int_new(0), string_new("zero"));
HashMap_insert(map, int_new(13), string_new("thirteen"));
HashMap_insert(map, int_new(22), string_new("twentytwo"));
HashMap_insert(map, int_new(34), string_new("thirtyfour"));
HashMap_insert(map, int_new(41), string_new("fortyone"));
return map;
}
/*
looking inside the Hashmap for the element
*/
void test_lookup(){
HashMap* map = create_five_elements_hash_map();
char** str = (char**)HashMap_lookup(map,int_new(13));
printf("result = %s\n", *str);
}
int main(){
test_lookup();
test_lookup();
test_lookup();
return 0;
}