У меня есть следующая структура моей HashTable:
typedef char *HashKey;
typedef int HashValue;
typedef struct sHashElement {
HashKey key;
HashValue value;
} HashElement;
typedef struct sHashTable {
HashElement *items;
float loadFactor;
} HashTable;
Я никогда не думал об этом до сих пор, но я только что понял, что есть два способа, как я могу это использовать:
Вариант 1:
void hashInitialize(HashTable *table, int tabSize) {
table->items = malloc(sizeof(HashElement) * tabSize);
if(!table->items) {
perror("malloc");
exit(1);
}
table->items[0].key = "AAA";
table->items[0].value = 45;
table->items[1].key = "BBB";
table->items[1].value = 82;
table->loadFactor = (float)2 / tabSize;
}
int main(void) {
HashTable t1;
int i;
hashInitialize(&t1, HASHSIZE);
for(i = 0; i < HASHSIZE - 1; i++) {
printf("PAIR(%d): %s, %d\n", i+1, t1.items[i].key, t1.items[i].value);
}
printf("LOAD FACTOR: %.2f\n", t1.loadFactor);
return 0;
}
Вариант 2:
void hashInitialize(HashTable **table, int tabSize) {
*table = malloc(sizeof(HashTable));
if(!*table) {
perror("malloc");
exit(1);
}
(*table)->items = malloc(sizeof(HashElement) * tabSize);
if(!(*table)->items) {
perror("malloc");
exit(1);
}
(*table)->items[0].key = "AAA";
(*table)->items[0].value = 45;
(*table)->items[1].key = "BBB";
(*table)->items[1].value = 82;
(*table)->loadFactor = (float)2 / tabSize;
}
int main(void) {
HashTable *t1 = NULL;
int i;
hashInitialize(&t1, HASHSIZE);
for(i = 0; i < HASHSIZE - 1; i++) {
printf("PAIR(%d): %s, %d\n", i+1, t1->items[i].key, t1->items[i].value);
}
printf("LOAD FACTOR: %.2f\n", t1->loadFactor);
return 0;
}
Вопрос 1. Обе они дают одинаковый результат. В main
оба примера выводят правильную пару ключ/значение. Итак, чем же они отличаются, кроме изменения синтаксиса (использование (*table)
вместо просто table
), дополнительного кода для выделения памяти для структуры HashTable
и объявления указателя HashTable
?
В последнее время я писал несколько структур данных, таких как стеки, связанные списки, двоичные деревья поиска и теперь хеш-таблицы. И для всех них я всегда использовал альтернативу 2. Но теперь я думаю, мог ли я использовать альтернативу 1 и упростить код, удалив большую часть *
и &
, которые повсюду.
Но я задаю этот вопрос, чтобы понять разницу между двумя методами, а также, почему, а также почему я должен использовать один по сравнению с другим.
Вопрос 2: Как видно из кода структуры, HashKey
— это указатель. Однако я не использую strdup
и malloc
для выделения места для этой строки. Как и почему это работает? Это нормально делать? Я всегда использовал malloc
или strdup
, где это уместно, при обработке динамических строк, иначе я получил бы много ошибок сегментации. Но этот код не дает мне никаких ошибок сегментации, и я не понимаю, почему и должен ли я делать это так.