Лично я не большой поклонник использования typedefs, особенно когда вы новичок. Я думаю, что это может быть отчасти то, что вас смущает. Вам лучше избегать таких вещей, как:
typedef struct hashtable * HashTablePtr;
Использование многих typedefs затруднит чтение вашего кода, так как вам нужно будет постоянно искать то, на что они ссылаются.
Основная проблема заключается в том, что вы выделяете память для размера указателя хеш-таблицы / списка, а не для размера их уважаемых структур. Я думаю, что код ниже показывает это хорошо. Вы также захотите проверить, сработали ли ваши распределения. Если malloc, calloc, realloc. и т.д. терпят неудачу, они возвращают NULL. Если это произойдет, и вы не проверите этот случай, вы получите ошибку segfault, и ваша программа потерпит крах.
Также следуйте стандарту c99 и поместите все объявления переменных в начало функции.
c99 std
Руководство пользователя malloc
struct hashtable *
createHashTable(unsigned int capacity){
struct hashtable *hash;
struct list *mylist;
/* You want to allocate size of the hash structure not the size of a pointer. */
hash = malloc(sizeof(struct hashtable));
// always make sure if the allocation worked.
if(hash == NULL){
fprintf(stderr, "Could not allocate hashtable\n");
return NULL;
}
hash->size = 0;
hash->capacity = capacity;
/* Unless you need the memory to be zero'd I would just use malloc here
* mylist = calloc(capacity, sizeof(struct list)); */
mylist = malloc(capacity * sizeof(struct list));
if(mylist == NULL){
fprintf(stderr, "Could not allocate list\n");
free(hash); /* free our memory and handle the error*/
return NULL;
}
mylist->head = NULL;
mylist->size = 0;
mylist->tail = NULL;
hash->list = mylist;
return hash;
}
Также не забудьте освободить свой список, прежде чем освободить свою хеш-таблицу:
free(myhash->list);
free(myhash);