c - 哈希表添加 - C

标签 c hashtable

在以下算法中出现一些段错误,以将元素添加到哈希表中的正确存储桶中。

我的结构是基本的:

struct kv {
    char* key;
    unsigned val;
    struct kv* next;
};

struct hashtable {
    struct kv** table;
    unsigned size;
}; 

还有我的错误函数:

    struct kv* ht_find_or_put(char* word, unsigned value,
                                  struct hashtablet* hashtable,
                                  unsigned (*hash)(char*))
    {
        unsigned index = hash(word) % hashtable->size;
        struct kv* ke = malloc(sizeof (struct kv));

        for (ke = hashtable->table[index]; ke != NULL; ke = ke->next)
        {
            if (strcmp(ke->key, word) == 0)
                return ke;
        }

        if (ke == NULL)
        {
            ke->key = word;
            ke->val = value;
            ke->next = hashtable->table[index];
            hashtable->table[index] = ke;
        }
   return ke;
}

我知道我还没有添加所有测试(如果 malloc 失败等)只是试图调试这个特定问题...

我这样分配我的 table :

struct hashtable* hashtable_malloc(unsigned size)
{
    struct hashtable *new_ht = malloc(sizeof(struct hashtable));
    new_ht->size = size;
    new_ht->table = malloc(sizeof(struct kv) * size);

    for(unsigned i = 0; i < size; i++)
        new_ht->table[i] = NULL;

    return new_ht;
}

任何形式的帮助将不胜感激。我才刚刚开始学习。

最佳答案

第一个问题是内存泄漏,例如- 您使用 malloc 分配内存,但是当您覆盖指针时会丢失对它的引用:

// allocate memory
struct kv* ke = malloc(sizeof (struct kv));
//   lose the reference
//   VVVVVVVVVVV
for (ke = hashtable->table[index]; ke != NULL; ke = ke->next)

可能导致段错误的第二个问题是您尝试取消引用空指针:

if (ke == NULL)
{
    // ke is NULL, you can't de-reference it
    ke->key = word;
    ke->val = value;
    ke->next = hashtable->table[index];
    hashtable->table[index] = ke;
}

恕我直言,解决方案是仅在找不到新元素时分配并放置新元素:

struct kv* ht_find_or_put(char* word, unsigned value, struct hashtablet* hashtable, unsigned (*hash)(char*))
{
    unsigned index = hash(word) % hashtable->size;
    struct kv* ke;

    // first we try to find the node
    for (ke = hashtable->table[index]; ke != NULL; ke = ke->next)
    {
        if (strcmp(ke->key, word) == 0)
            return ke;
    }

    // didn't find it - lets create and put a new one.    
    if (ke == NULL)
    {
        ke = malloc(sizeof (struct kv));
        // later add a check if the allocation succeded...
        ke->key = word;
        ke->val = value;
        ke->next = hashtable->table[index];
        hashtable->table[index] = ke;
    }
    return ke;
}

由于我不想引入全新的代码,这只会让您感到困惑,因此我对原始代码进行了最小的更改。

关于c - 哈希表添加 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34238665/

相关文章:

c - 动态二维数组

c - 通过从中删除特定的行和列来缩小二维数组的大小

c - 如何反转链表

java - java中的哈希表给了我最后存储的值,但不是正确的值

matlab - MATLAB 中的哈希表

c - struct sockaddr_un 与 sockaddr

c - 在没有 VLA 的情况下传递可变大小的多维数组

c++ - 查找表究竟是如何工作的以及如何实现它们?

c# - 在 C# 中将哈希表转换为字典

java - 查找数组中两个数字的总和是否等于 k