在C中将项目添加到我的哈希表中

在C中将项目添加到我的哈希表中,c,hashtable,C,Hashtable,我正在尝试向哈希表中添加一项,我使用了很多 printf想看看发生了什么,但它看起来应该添加它,但实际上不是 这是我的代码: struct hashnode_s { char *key; ValueType tag; union { int IntegerValue; char *StringValue; }u; struct hashnode_s *next; }; 我试图模仿GCC编译器。 用我的哈希表 typ

我正在尝试向哈希表中添加一项,我使用了很多 printf想看看发生了什么,但它看起来应该添加它,但实际上不是

这是我的代码:

struct hashnode_s {
    char *key;
    ValueType tag;
    union
    {
        int IntegerValue;
        char *StringValue;
    }u;
    struct hashnode_s *next;
};
我试图模仿GCC编译器。 用我的哈希表

typedef struct hashtbl {
    hash_size size;
    struct hashnode_s **nodes;
    hash_size (*hashfunc)(const char *);
} HASHTBL;
还有我的插入方法

int hashtbl_InsertString(HASHTBL *hashtbl, const char *key, const char *value)
{
    struct hashnode_s *node;
    hash_size hash;

    hash = SearchForHashIndex(hashtbl, key, value);
    if(hash ==-1)
    {
        hash=hashtbl->hashfunc(key);
    }

    fprintf(stderr, "hashtbl_insert() key=%s, hash=%d\n\n\n", key, hash);

    node=hashtbl->nodes[hash];
    while(node)
    {   
        printf("In while\n\n\n\n\n");   
        /* This Code isn't correct 
        if(!strcmp(node->key, key)) {
            node->data=data;
            return 0;
        }*/
        node=node->next;
    }

    if(!(node=malloc(sizeof(struct hashnode_s)))) return -1;
    if(!(node->key=mystrdup(key))) {
        free(node);
        return -1;
    }
    node->key = key;
    node->tag = StringConst;
    node->u.StringValue = value;

    node->next=hashtbl->nodes[hash];    

    printf("ADDING HASH NODE \n\n\n");

    hashtbl->nodes[hash]=node;

    return 0;
}
我在搜索方法时不断得到空值。不应该是这样的。我插对了吗

int SearchForHashIndex(HASHTBL *hashtbl, const char *key, const char *value)
{
    printf("INSIDE SEARCH FOR HASH INDEX \n\n\n\n\n");
    int i;

    for(i=0; i < CurrentHashSize; i++)
    {   
        struct hashnode_s *node;    
        node = hashtbl->nodes[i];
        printf("%d\n",i);
        if(node == NULL)
        {
            printf("NULL");
        }
        while(node)
        {
            if(strcmp(node->key,key) || strcmp(node->u.StringValue,value))
            {
                printf("INSIDE HERE!\n");
                return i;
                printf("returning %d\n",i);
            }
            node = node->next;
        }
    }
    printf("returning -1\n");
    return -1;
}
int SearchForHashIndex(HASHTBL*HASHTBL,const char*键,const char*值)
{
printf(“哈希索引的内部搜索\n\n\n\n”);
int i;
对于(i=0;inodes[i];
printf(“%d\n”,i);
if(node==NULL)
{
printf(“空”);
}
while(节点)
{
if(strcmp(节点->键,键)| | strcmp(节点->u.StringValue,值))
{
printf(“此处内部!\n”);
返回i;
printf(“返回%d\n”,i);
}
节点=节点->下一步;
}
}
printf(“返回-1\n”);
返回-1;
}
strcmp()在成功进行比较时返回0。您需要在搜索函数中更改if()条件

此外,插入例程中的此块:

node=hashtbl->nodes[hash];
while(node)
{   
    printf("In while\n\n\n\n\n");   
    /* This Code isn't correct 
    if(!strcmp(node->key, key)) {
        node->data=data;
        return 0;
    }*/
    node=node->next;

}
是无用的,因为您只是在之后直接将新分配的内存分配给节点。

strcmp()在进行成功比较时返回0。您需要在搜索函数中更改if()条件

此外,插入例程中的此块:

node=hashtbl->nodes[hash];
while(node)
{   
    printf("In while\n\n\n\n\n");   
    /* This Code isn't correct 
    if(!strcmp(node->key, key)) {
        node->data=data;
        return 0;
    }*/
    node=node->next;

}

是无用的,因为您只是在之后直接将新分配的内存分配给节点。

这看起来不正确:

if(!(node->key=mystrdup(key))) {
    free(node);
    return -1;
}
node->key = key;

您正在将
节点->键设置为(显然)提供的
键的副本;然后立即用函数参数覆盖该指针,这不太可能正确。

这看起来不正确:

if(!(node->key=mystrdup(key))) {
    free(node);
    return -1;
}
node->key = key;

您正在将
节点->键设置为(显然)提供的
键的副本;然后立即用函数参数覆盖该指针,这不太可能是正确的。

如果哈希函数是可靠的(并且必须是哈希函数),则搜索函数不必遍历所有链接列表。对于
循环,您不应该需要外部的
,只需将
i
设置为
hashtabl->hashfunc(key)
,然后在该列表中搜索元素即可。若它不在那个列表中,那个么它不应该在任何列表中,若它在那个列表中,那个么你们的插入函数肯定是错误的

实际上,搜索函数应该返回
hashtabl->hashfunc(key)
或-1


此外,如果有人对不同的对象使用相同的键,会发生什么情况?

如果您的哈希函数是可靠的(并且必须是哈希函数),则您的搜索函数不必遍历所有链接列表。对于
循环,您不应该需要外部的
,只需将
i
设置为
hashtabl->hashfunc(key)
,然后在该列表中搜索元素即可。若它不在那个列表中,那个么它不应该在任何列表中,若它在那个列表中,那个么你们的插入函数肯定是错误的

实际上,搜索函数应该返回
hashtabl->hashfunc(key)
或-1


此外,如果有人对不同的对象使用相同的键,会发生什么情况?

首先,您的
printf(“返回%d\n”,i)
将永远不会计算,因为它在
return
语句之后。是的,我注意到了。我忘了删除lolCode,它的格式是缩进四个空格(还有一个按钮),而不是使用标签。首先,你的
printf(“returning%d\n”,i)
永远不会计算,因为它在
return
语句之后。是的,我注意到了。这是我在那里忘记删除的东西。代码的格式是缩进四个空格(也有一个按钮),而不是使用标记。我试图通过添加myu第一个节点来完成。哈哈,我都搞不懂。一旦我得到了它,我就可以在下一个节点上添加更多节点,这样该部分就可以ignored@Kevin:在我看来,这段代码将为第一个节点执行。@Kevin-@caf引用的部分不是注释掉的部分
node->key=key
覆盖先前的
node->key
值,该值是您分配给
mystrdup
的内存。您正在丢弃分配的内存(这是一个漏洞),并用用户传递给函数的任何参数替换它。IM delayed!!每次我找到一个特定的“定义”叙述时,我都会继续重新创建我的表格!!!我忘了重置布尔值!!我只是想通过添加myu第一个节点。哈哈,我都搞不懂。一旦我得到了它,我就可以在下一个节点上添加更多节点,这样该部分就可以ignored@Kevin:在我看来,这段代码将为第一个节点执行。@Kevin-@caf引用的部分不是注释掉的部分
node->key=key
覆盖先前的
node->key
值,该值是您分配给
mystrdup
的内存。您正在丢弃分配的内存(这是一个漏洞),并用用户传递给函数的任何参数替换它。IM delayed!!每次我找到一个特定的“定义”叙述时,我都会继续重新创建我的表格!!!我忘了重置布尔值!!我认为该块用于OP何时可以使“添加节点”部分工作,检查节点是否已添加,并且在完成分配新节点之前可能会返回。我认为该块用于OP何时可以使“添加节点”部分工作,检查节点是否已添加,并且在完成分配新节点之前可能会返回。这是我第一次处理哈希表。我还在挣扎哈哈。试着去理解,而我通常不会写程序