我正在使用哈希表实现UThash。
我使用原语插入元素:
HASH_ADD(hh,hash_table,key,keylen,elem);
使用基元检索元素:
HASH_FIND(hh,hash_table,key,keylen,elem);
由于某些原因我不知道,当我调用一个函数时,哈希查找的行为正在被修改。也就是说, uthash找不到表格中的元素。
我怀疑记忆已经在某种程度上受到了损害。
触发此失败的功能无需执行任何代码即可使UThash失败:
//Note: ct = custom_type
int func1(ct1 *ptr1, ct2 *ptr2, ct3 *ptr3,char **buffer,size_t *size)
{
HASH_FIND(...) //does not work
/**
* code
*/
return 0;
}
int func2(ct1 *ptr1,ct2 *ptr2,ct3 *ptr3)
{
char *buffer;
size_t buf_size;
/**
* code
*/
HASH_FIND(...) // works!
if(func1(ptr1,ptr2,ptr3,&buffer,&buf_size)){
//code
}/*error*/
return 0;
}
int func3(ct1 *ptr1,ct2 *ptr2,ct3 *ptr3)
{
char *buffer;
size_t buf_size;
HASH_FIND(...) // works!
if(func1(ptr1,ptr2,ptr3,&buffer,&buf_size)){
//code
}/*error*/
/**
* code
*/
return 0;
}
因此在 func2()和 func3()中都会发生相同的行为。调用 func1()后,hash_find()开始失败。
所有其余代码都完美正确地执行。
我明显的问题是什么可能导致这种类型的失败?
感谢您阅读并随意提出任何其他信息。
答案 0 :(得分:2)
这可能是由于将几个具有相同键的项添加到哈希中。如果使用uthash,则需要确保结构中没有重复的键,或者提供一个包装函数,用旧的项替换旧项。否则,结构的行为是不可预测的,并可能导致您所描述的失败。
如果您有可能生成重复的密钥 程序,你必须在添加之前明确检查唯一性 哈希的关键。如果密钥已经在哈希中,您可以简单地 修改哈希中的现有结构而不是添加项。 将具有相同键的两个项添加到哈希表是错误的。
答案 1 :(得分:0)
这是因为您正在散列指针而不是数据。
答案 2 :(得分:0)
当我的密钥类型为 unsigned char 时,我遇到了类似的问题, 用 int 替换后,HASH_FIND_INT开始正常工作。进一步的研究表明,打扰签名字符和 unsigned char 是不合适的,而 short int 和 unsigned short int 似乎工作也很好。
可能8位不足以使散列函数计算算法正常运行。 请注意,具有 unsigned char 操作的原始代码是间歇性的,代码在某些版本中有效,在其他版本中无效(与uthash无关的更改)。
结论:使用 signed int 类型的键来正确操作HASH_FIND_INT,或使用 short int 或 unsigned short ,风险自负。
答案 3 :(得分:0)
也许,事实并非如此,但是当我使用struct
作为HASH_FIND
的关键字时,我遇到了类似的问题。使用struct
确定密钥长度时,请注意sizeof()
填充。如果您没有正确初始化密钥,则此填充可能是您在查找时找不到uthash
的原因。
答案 4 :(得分:0)
正如@yerden所述,由于struct
填充,我也遇到了这个问题。在gcc上,将带有打包属性的struct
定义为{p>
struct __attribute__((__packed__)) a_struct {
char a, b;
unsigned int i;
};
uthash manual中提到了结构键的问题,解决方法是将struct
归零,然后再将其添加到哈希中,如此处所示。
另一种解决方案是learn about structure packing并重新组织struct
,因此填充不是问题(或不是问题)。另一个有用的stack overflow question中提供了结构打包的快速概述。