I’m trying to build my own Hash Table in C from scratch as an exercise and I’m doing one little step at a time. But I’m having a little issue…
I’m declaring the Hash Table structure as pointer so I can initialize it with the size I want and increase it’s size whenever the load factor is high.
The problem is that I’m creating a table with only 2 elements (it’s just for testing purposes), I’m allocating memory for just those 2 elements but I’m still able to write to memory locations that I shouldn’t. And I also can read memory locations that I haven’t written to.
Here’s my current code:
#include <stdio.h>
#include <stdlib.h>
#define HASHSIZE 2
typedef char *HashKey;
typedef int HashValue;
typedef struct sHashTable {
HashKey key;
HashValue value;
} HashEntry;
typedef HashEntry *HashTable;
void hashInsert(HashTable table, HashKey key, HashValue value) {
}
void hashInitialize(HashTable *table, int tabSize) {
*table = malloc(sizeof(HashEntry) * tabSize);
if(!*table) {
perror("malloc");
exit(1);
}
(*table)[0].key = "ABC";
(*table)[0].value = 45;
(*table)[1].key = "XYZ";
(*table)[1].value = 82;
(*table)[2].key = "JKL";
(*table)[2].value = 13;
}
int main(void) {
HashTable t1 = NULL;
hashInitialize(&t1, HASHSIZE);
printf("PAIR(%d): %s, %d\n", 0, t1[0].key, t1[0].value);
printf("PAIR(%d): %s, %d\n", 1, t1[1].key, t1[1].value);
printf("PAIR(%d): %s, %d\n", 3, t1[2].key, t1[2].value);
printf("PAIR(%d): %s, %d\n", 3, t1[3].key, t1[3].value);
return 0;
}
You can easily see that I haven’t allocated space for (*table)[2].key = "JKL"; nor (*table)[2].value = 13;. I also shouldn’t be able read the memory locations in the last 2 printfs in main().
Can someone please explain this to me and if I can/should do anything about it?
EDIT:
Ok, I’ve realized a few things about my code above, which is a mess… But I have a class right now and can’t update my question. I’ll update this when I have the time. Sorry about that.
EDIT 2:
I’m sorry, but I shouldn’t have posted this question because I don’t want my code like I posted above. I want to do things slightly different which makes this question a bit irrelevant. So, I’m just going to assume this was question that I needed an answer for and accept one of the correct answers below. I’ll then post my proper questions…
Just don’t do it, it’s undefined behavior.
It might accidentially work because you write/read some memory the program doesn’t actually use. Or it can lead to heap corruption because you overwrite metadata used by the heap manager for its purposes. Or you can overwrite some other unrelated variable and then have hard times debugging the program that goes nuts because of that. Or anything else harmful – either obvious or subtle yet severe – can happen.
Just don’t do it – only read/write memory you legally allocated.