Uthash добавление новой записи вHashMap - PullRequest
0 голосов
/ 07 ноября 2019

Я хочу создать хеш-карту с uthash .

Я хочу, чтобы ключ и значение были структурой, содержащей String и size_t, например:

typedef struct hash_ptr {
    char* string;
    size_t len;
}hash_ptr;

Сама хеш-таблица выглядит следующим образом:

typedef struct hash_map_entry {
    struct hash_ptr *key;
    struct hash_ptr *value;
    UT_hash_handle hh;
}hash_map_entry;

Чтобы добавить новые записи на карту, я написал новую функцию add_entry ():

void add_entry(hash_map_entry *map, hash_ptr *key, hash_ptr *value) {
    hash_map_entry *entry;
    HASH_FIND(hh, map, key, sizeof *key, entry);
    if (entry == NULL) {
        entry = (hash_map_entry*) malloc(sizeof *entry);
        memset(entry, 0, sizeof *entry);
        entry->value = value;
        entry->key = key;
        HASH_ADD(hh, map, key, sizeof *key, entry);
    }
}

Однако, после инициализации и вызова add_entry () ...

hash_map_entry *map = NULL;

hash_ptr *key = (hash_ptr*) malloc(sizeof *key);
memset(key, 0, sizeof *key);
key->string = "Is this the Krusty Krab?";
key->len = strlen(key->string);

hash_ptr *value = (hash_ptr*) malloc(sizeof *value);
memset(value, 0, sizeof *value);
value->string = "No, this is Patrick!";
value->len = strlen(value->string);

add_entry(map, key, value);

... HASH_FIND не находит добавленную запись:

hash_map_entry *find_me;
HASH_FIND(hh, map, key, sizeof *key, find_me);

и find_me имеет значение NULL.

Я следовал инструкциям по использованию структуры в качестве ключа из официального руководства пользователя .

Где я не прав?

1 Ответ

1 голос
/ 07 ноября 2019

Это самая простая модификация, которую я могу придумать. Изменения по сравнению с оригиналом:

  1. Измените первый параметр add_entry с hash_map_entry *map на hash_map_entry **map и измените код соответствующим образом.

  2. Используйте HASH_ADD_KEYPTR для хеширования содержимого строки внутри struct hash_ptr вместо хеширования самого struct hash_ptr. ПРИМЕЧАНИЕ: код предполагает, что элемент len - это длина объекта, на который указывает элемент string, в байтах.

  3. Относится к 2, измените использованиеHASH_FIND для хеширования содержимого строки внутри struct hash_ptr.

Вот результат:

#include <stdio.h>
#include <stdlib.h>
#include "uthash.h"

typedef struct hash_ptr {
    char* string;
    size_t len;
}hash_ptr;

typedef struct hash_map_entry {
    struct hash_ptr *key;
    struct hash_ptr *value;
    UT_hash_handle hh;
}hash_map_entry;

void add_entry(hash_map_entry **map, hash_ptr *key, hash_ptr *value) {
    hash_map_entry *entry;
    HASH_FIND(hh, *map, key->string, key->len, entry);
    if (entry == NULL) {
        entry = (hash_map_entry*) malloc(sizeof *entry);
        memset(entry, 0, sizeof *entry);
        entry->value = value;
        entry->key = key;
        HASH_ADD_KEYPTR(hh, *map, key->string, key->len, entry);
    }
}

int main(void)
{
    hash_map_entry *map = NULL;

    hash_ptr *key = (hash_ptr*) malloc(sizeof *key);
    memset(key, 0, sizeof *key);
    key->string = "Is this the Krusty Krab?";
    key->len = strlen(key->string);

    hash_ptr *value = (hash_ptr*) malloc(sizeof *value);
    memset(value, 0, sizeof *value);
    value->string = "No, this is Patrick!";
    value->len = strlen(value->string);

    add_entry(&map, key, value);

    hash_map_entry *find_me;
    HASH_FIND(hh, map, key->string, key->len, find_me);
    if (find_me)
    {
        printf("found key=\"%s\", val=\"%s\"\n", find_me->key->string, find_me->value->string);
    }
    else
    {
        printf("not found\n");
    }
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...