3

我正在使用哈希表实现 UThash。

我正在使用原语插入元素:

    HASH_ADD(hh,hash_table,key,keylen,elem);

并使用原语检索元素:

    HASH_FIND(hh,hash_table,key,keylen,elem);

出于某种我不知道的原因,当我调用函数时,哈希查找的行为正在被修改。也就是说,uthash 没有找到 table 中存在的元素

我怀疑记忆在某种程度上受到了损害。

触发这个失败的函数不需要执行任何代码使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()中都会发生相同的行为。hash_find() 在我调用func1()后开始失败 。

所有其余的代码都完美且正确地执行。

我明显的问题是什么会导致这种类型的失败?

感谢您阅读并随时询问任何其他信息。

4

5 回答 5

2

这可能是由于将具有相同键的多个项目添加到哈希中引起的。如果你使用 uthash,你需要确保你的结构中没有重复的键,或者提供一个包装函数来用新的替换旧的项目。否则,结构的行为是不可预测的,并可能导致您描述的故障。

来自uthash 用户指南

如果您的程序有可能生成重复键,则必须在将键添加到散列之前明确检查唯一性。如果键已经在散列中,您可以简单地修改散列中的现有结构,而不是添加项。将具有相同键的两个项目添加到哈希表是错误的。

于 2012-12-29T16:43:15.680 回答
0

那是因为您正在散列指针而不是数据。

使用HASH_ADD_KEYPTR

于 2015-03-17T15:10:29.667 回答
0

也许不是这样,但是当我使用 somestruct作为HASH_FIND. 用于确定密钥长度时请注意struct填充。如果您没有正确初始化密钥,则此填充可能是您查找时找不到sizeof()的原因。uthash

于 2016-04-08T09:07:14.090 回答
0

我有类似的问题,当我的密钥类型为unsigned char时,用int HASH_FIND_INT替换它后开始正常工作。进一步的调查表明,打扰signed charunsigned char是不合适的,而short intunsigned short int似乎也可以正常工作。

可能 8 位不足以让哈希函数计算算法正常运行。请注意,带有unsigned char操作的原始代码是断断续续的,代码在某些版本中有效,在其他版本中无效(与 uthash 无关的更改)。

结论:使用signed int类型的密钥正确操作 HASH_FIND_INT,或使用short intunsigned short风险自负。

于 2016-02-03T09:24:40.627 回答
0

struct正如@yerden 所提到的,由于填充,我也遇到了这个问题。struct在 gcc 上,使用打包属性定义 很容易,但速度很慢,如

struct __attribute__((__packed__)) a_struct {
    char a, b;
    unsigned int i;
};

uthash结构键手册中提到了这个问题,解决方案是struct在将其添加到散列之前将其清零,如此处所示。

另一个解决方案是了解结构包装并重新组织你的struct填充不是(或更少)问题。在另一个有用的堆栈溢出问题中给出了结构打包的快速概述。

于 2019-03-23T15:10:57.083 回答