调用函数会使UThash失败

问题描述 投票:3回答:5

我们将在这个散列表上进行植入。

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

    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()开始失败。

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

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

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

c function pointers
5个回答
2
投票

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

来自uthash user guide

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


0
投票

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

使用HASH_ADD_KEYPTR


0
投票

我有类似的问题,当我的键有类型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,风险自负。


0
投票

也许,事实并非如此,但是当我使用一些struct作为HASH_FIND的关键时,我遇到了类似的问题。当您使用struct确定密钥长度时,请注意sizeof()填充。如果你没有正确初始化一个键,这个填充可能是你查找时uthash找不到的原因。


0
投票

由于@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给出了结构包装的快速概述。

© www.soinside.com 2019 - 2024. All rights reserved.