【问题标题】:uthash adding a new entry to a <struct, struct> hashmaputhash 向 <struct, struct> hashmap 添加新条目
【发布时间】:2020-03-04 06:36:50
【问题描述】:

我想用uthash 创建一个哈希图。

我希望键和值是一个结构,包含一个字符串和一个 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。

我遵循了使用结构体作为 official user guide 中的键的说明。

我哪里错了?

【问题讨论】:

  • 这是否有效:HASH_ADD_KEYPTR(hh, map, key-&gt;string, key-&gt;len, entry);HASH_FIND(hh, map, key-&gt;string, key-&gt;len, find_me);
  • @IanAbbott 不幸的是,结果相同。
  • 我认为您需要按照Specifying an alternate key comparison function 中的说明定义自己的HASH_FUNCTIONHASH_KEYCMP 宏。或者将 key 更改为 char * 并单独存储密钥长度,或者假设密钥是空终止的字符串指针并使用 String keys 中的“结构中的字符串 指针”示例.
  • @IanAbbott 根据this,使用结构作为键应该可以工作。
  • @m42v1r 是的,只要清除结构填充并且正在比较的结构内的指针匹配。问题是,你是比较指针还是指针指向的东西?

标签: c struct hashmap uthash


【解决方案1】:

这是我能想到的最简单的修改。与原作的变化是:

  1. add_entry的第一个参数从hash_map_entry *map改为hash_map_entry **map并相应调整代码。

  2. 使用HASH_ADD_KEYPTRstruct 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多