Reputation: 13
I'm implementing a hashtable that has a remove_entry function as well as a clear_table function. Right now I'm getting memory read errors pertaining to the remove_entry function. And help would be greatly appreciated
These are my structures:
typedef struct bucket {
char *key;
void *value;
struct bucket *next;
} Bucket;
typedef struct {
int key_count;
int table_size;
void (*free_value)(void *);
Bucket **buckets;
} Table;
Here's my function:
int remove_entry(Table * table, const char *key){
unsigned int hc = 0;
Bucket *curr_b;
Bucket *next_b;
if(table == NULL || key == NULL){
return FAIL;
} else {
hc = hash_code(key)%(table->table_size);
if(table->buckets[hc] != NULL){
curr_b = table->buckets[hc];
/*Check the buckets in linked list*/
while(curr_b != NULL){
next_b = curr_b->next;
if(strcmp(curr_b->key,key) == 0){
free(curr_b->key);
if(table->free_value != NULL){
table->free_value(curr_b->value);
}
free(curr_b);
curr_b = NULL;
table->key_count--;
return SUCC;
} else {
curr_b = next_b;
}
}
return FAIL;
}
return FAIL;
}
}
The memory leaks come after removing an entry, and trying to read the table after. I don't think I removed things right.
Memory errors:
Can't figure out how to copy/paste from terminal, so they all say things like
Invalid read of size __
Address ____ is __ bytes inside a block of size ___ free'd
Upvotes: 1
Views: 124
Reputation: 7044
You need to consider the case where table->buckets[hc]
is the bucket you free.
Right before free(curr_b->key);
add:
if(curr_b == table->buckets[hc]) {
table->buckets[hc] = next_b;
}
As it is now, you free a bucket, but table->buckets[hc]
still points to it. So the next time you read it you are reading free'ed memory. Thus the error.
Also, you need to keep track of the previous bucket so you can point the previous bucket to the next bucket when you remove a bucket.
Upvotes: 1