c - 使用结构作为键修改示例时出现 UTHash 段错误

标签 c segmentation-fault valgrind uthash

我正在尝试通过修改标准键类型、结构键示例来使用 UTHash,以达到我的目的,请参见以下链接:

https://troydhanson.github.io/uthash/userguide.html#_structure_keys

这是我修改后的代码(精简以显示我将问题隔离到的位置)

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "uthash.h"

typedef struct StateKey
{
    // array of bools that gives the instances that are present.
    bool *instancesAtNode_BoolArray;

} t_StateKey;


typedef struct State
{
    // State Key.  
    t_StateKey stateKey_StateKey;

    // probability of being in the given state
    double p;

    // UTHash handle array used for hashing 
    UT_hash_handle hh;

} t_State;

int main(int argc, char *argv[]) {

    double a = .80;
    double b = .2;     
    double c = .1;     
    //double d = .7;    

    t_State *state, *stateHead, *toFind = NULL;
    state = (t_State *) malloc(sizeof(t_State));
    memset(state, 0, sizeof(t_State));
    state->stateKey_StateKey.instancesAtNode_BoolArray = NULL;
    state->p = 1;

    HASH_ADD(hh, stateHead, stateKey_StateKey, sizeof(t_StateKey), state);

    return 0;
}

请注意,在 main 中我已经注释掉了变量 d。运行下面的代码不会出现任何问题,但是当我取消注释代码时会引发段错误。对我来说,这表明存在某种越界错误,只有当代码具有特定的大小/组织时,操作系统才会发现(这就是为什么注释掉看似不相关的变量可以防止该错误)。

我不知道自己做错了什么,因为据我所知,我正在遵循给出的示例。看看 Valgrind 我得到以下内容

==94553== Conditional jump or move depends on uninitialised value(s)
==94553==    at 0x10000195F: main (testNewMcUniverseMain.c:40)
==94553==  Uninitialised value was created by a stack allocation
==94553==    at 0x7FFF5FC01036: _dyld_start (in /usr/lib/dyld)
==94553== 
==94553== Use of uninitialised value of size 8
==94553==    at 0x100001A9F: main (testNewMcUniverseMain.c:40)
==94553==  Uninitialised value was created by a stack allocation
==94553==    at 0x7FFF5FC01036: _dyld_start (in /usr/lib/dyld)
==94553== 
==94553== Use of uninitialised value of size 8
==94553==    at 0x100001ABF: main (testNewMcUniverseMain.c:40)
==94553==  Uninitialised value was created by a stack allocation
==94553==    at 0x7FFF5FC01036: _dyld_start (in /usr/lib/dyld)
==94553== 
==94553== Use of uninitialised value of size 8
==94553==    at 0x100001ACB: main (testNewMcUniverseMain.c:40)
==94553==  Uninitialised value was created by a stack allocation
==94553==    at 0x7FFF5FC01036: _dyld_start (in /usr/lib/dyld)
==94553== 
==94553== Use of uninitialised value of size 8
==94553==    at 0x100001AE6: main (testNewMcUniverseMain.c:40)
==94553==  Uninitialised value was created by a stack allocation
==94553==    at 0x7FFF5FC01036: _dyld_start (in /usr/lib/dyld)
==94553== 
==94553== Invalid write of size 8
==94553==    at 0x100001AEE: main (testNewMcUniverseMain.c:40)
==94553==  Address 0x5400313d524f4c5f is not stack'd, malloc'd or 
(recently) free'd
==94553== 
==94553== Signal 11 being dropped from thread 0's queue
==94553== Signal 11 being dropped from thread 0's queue
==94553== Signal 11 being dropped from thread 0's queue
==94553== Signal 11 being dropped from thread 0's queue

(Repeats this line forever, I had to kill the terminal)

我做错了什么还是UTHash 的问题?如果是 UTHash,我可以用于 C(不是 C++)的另一个哈希表库是什么?

为了简单起见,我从下面引用的源中复制了 UTHash 示例代码

#include <stdlib.h>
#include <stdio.h>
#include "uthash.h"

typedef struct {
  char a;
  int b;
}     record_key_t;

typedef struct {
    record_key_t key;
    /* ... other data ... */
    UT_hash_handle hh;
} record_t;

int main(int argc, char *argv[]) {
    record_t l, *p, *r, *tmp, *records = NULL;

    r = (record_t *)malloc(sizeof *r);
    memset(r, 0, sizeof *r);
    r->key.a = 'a';
    r->key.b = 1;
    HASH_ADD(hh, records, key, sizeof(record_key_t), r);

    memset(&l, 0, sizeof(record_t));
    l.key.a = 'a';
    l.key.b = 1;
    HASH_FIND(hh, records, &l.key, sizeof(record_key_t), p);

    if (p) printf("found %c %d\n", p->key.a, p->key.b);

    HASH_ITER(hh, records, p, tmp) {
       HASH_DEL(records, p);
       free(p);
    }
    return 0;
}

最佳答案

我有一个愚蠢的。

来自示例

record_t l, *p, *r, *tmp, *records = NULL;

将仅将记录初始化为空。由于 UTHash 需要将“头”(在本例中为记录)初始化为 null,因此该示例有效。在我的示例中,头部是“stateHead”并且未初始化为 null。出于某种原因,我决定这样做

t_State *state, *stateHead, *toFind = NULL;

将所有这些指针设置为 null(这不是 C 的工作方式)。

关于c - 使用结构作为键修改示例时出现 UTHash 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53642712/

相关文章:

c++ - 一元减号和有符号到无符号的转换

c - 调试 C 代码

c - strtok段错误,仅在输入文件的第一行为空时给出段错误

c++ - valgrind 使用 --trace-children=yes 得到的结果不正确

C getline内存泄漏不同的行为

将包含 12 位数字的 16 位数组转换为 8 位连续数组

有人能告诉我哪里出了问题吗?我该如何替换 C 中的字符串?

c - gcc-10.0.1 特定的段错误

c - 第二次函数调用导致段错误

c - 使用 Valgrind 检查后如何查找和删除我的 C 程序中的内存泄漏和错误