我们将在这个散列表上进行植入。
我正在使用原语插入元素:
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()开始失败。
所有其余的代码都完美而正确地执行。
我明显的问题是什么可能导致这种类型的失败?
感谢您阅读并随意提出任何其他信息。
这可以通过将具有相同键的多个项添加到散列中来实现。如果使用uthash,则需要确保结构中没有重复的键,或者提供一个包装函数,用旧的项替换旧项。否则,结构的行为是不可预测的,并可能导致您描述的失败。
如果您的程序可能生成重复键,则必须在将键添加到哈希之前显式检查唯一性。如果密钥已经在哈希中,则可以简单地修改哈希中的现有结构,而不是添加项。将具有相同键的两个项添加到哈希表是错误的。
那是因为你正在散列指针而不是数据。
我有类似的问题,当我的键有类型unsigned char后,用int替换它后HASH_FIND_INT开始正常工作。进一步的研究表明,打扰签名的char和unsigned char是不合适的,而short int和unsigned short int似乎也可以正常工作。
可能8位不足以使散列函数计算算法正常运行。请注意,具有unsigned char操作的原始代码是间歇性的,代码在某些版本中工作,在其他版本中不起作用(与uthash无关的更改)。
结论:使用signed int类型的键来正确操作HASH_FIND_INT,或者使用short int或unsigned short,风险自负。
也许,事实并非如此,但是当我使用一些struct
作为HASH_FIND
的关键时,我遇到了类似的问题。当您使用struct
确定密钥长度时,请注意sizeof()
填充。如果你没有正确初始化一个键,这个填充可能是你查找时uthash
找不到的原因。
由于@yerden提到的struct
填充,我也遇到了这个问题。在gcc上,使用packed属性定义struct
很容易,但很慢
struct __attribute__((__packed__)) a_struct {
char a, b;
unsigned int i;
};
在uthash manual中为结构键提到了这个问题,解决方法是在将struct
添加到哈希之前将其清零,如此处所示。
另一个解决方案是qazxsw poi并组织你的qazxsw poi所以padding不是(或更少)一个问题。另一个有用的learn about structure packing给出了结构包装的快速概述。