调用函数会使UThash失败

时间:2012-12-11 20:13:59

标签: c function pointers

我正在使用哈希表实现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()开始失败。

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

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

感谢您阅读并随意提出任何其他信息。

5 个答案:

答案 0 :(得分:2)

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

来自uthash user guide

  

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

答案 1 :(得分:0)

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

使用HASH_ADD_KEYPTR

答案 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中提供了结构打包的快速概述。