I'm trying to implement a hash table in C. I'm using open addressing/linear probing to resolve collisions, so that if the program tries to create a new entry and the key hashes to a slot which is already in use, the entry will occupy the next available slot. I finally got my search and insert functions to stop segfaulting, but my delete function doesn't correctly delete hash table entries and I'm not sure why.
My hash table is implemented as an array of pointers to Item structures. The Item structure contains a key string and a data value (just an int for now.) My delete function calls free()
on the pointer to the item it needs to delete and sets that value in the array to NULL. However, the function seems to only delete the key string from the Item structure. Subsequent calls to ht_search()
with the same key yield NULL as expected, but a pointer to the item pre-deletion still allows the program to access the item's value. I'm not sure why this is and can't figure it out.
Relevant parts of my code: (Let me know if I should include additional functions like ht_insert()
and ht_search()
in my example.)
#define HASHTABLE_SIZE 1000
#define KEY_SIZE 64
typedef struct {
char key[KEY_SIZE];
int value;
} Item;
Item *hashtable[HASHTABLE_SIZE];
unsigned int
ht_hash(const char *key)
{
unsigned int sum = 0;
for (; *key; ++key) {
sum = sum * 101 + *key;
}
sum %= HASHTABLE_SIZE;
return sum;
}
Item
*ht_delete(const char *key)
{
unsigned int hash = ht_hash(key);
unsigned int i = hash;
for (;; ++i) {
i %= HASHTABLE_SIZE;
if (hashtable[i] && !strcmp(key, hashtable[i]->key))
break;
if (i == hash)
return -1;
}
free(hashtable[i]);
hashtable[i] = NULL;
return hashtable[i];
}
int
main(void)
{
Item *sel;
char *s = "foobar";
int data = 12345;
/* everything is fine so far */
sel = ht_insert(s, data);
/* this sets the 'key' field in sel to an empty string,
* but the value field is still accessible? */
ht_delete(s);
/* sel becomes null */
sel = ht_search(s);
return 0;
}
Does anyone know why ht_delete
doesn't fully delete the Item structure? What's going on?