У меня есть следующее для моей структуры 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
, где это уместно, при обработке динамических строк, иначе я бы получил много ошибок сегментации. Но этот код не дает мне никаких ошибок сегментации, и я не понимаю, почему и если я должен сделать это так.