【问题标题】:Double hashing closed hashing hash table issue双散列封闭散列表问题
【发布时间】:2020-11-27 17:59:00
【问题描述】:

我不明白出了什么问题。我使用橡皮鸭技术多次完成该程序。请问有什么问题?

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

enum state {legitimate, empty, deleted};

typedef struct 
{

    enum state info;
    char *key;
    char *value;

}cell;

typedef struct 
{

    cell *cells;
    unsigned int size;

}hash_table;

 
unsigned int
hash1(const char *key, unsigned int size)
{
    unsigned int hash = 0;
    
    for(unsigned int i = 0; key[i]; i++)
    {
        hash = (hash << 5) + key[i];
    }

    return (hash%size);

}

unsigned int
hash2(const char *key)
{
    unsigned int hash = 0;
    unsigned int prime = 3;
    
    for(unsigned int i = 0; key[i]; i++)
    {
        hash = prime - (key[i] % prime);
    }

    return (hash);

}


hash_table*
initialize(unsigned int size)
{
    hash_table *H = malloc(sizeof(*H));
    H->cells = malloc(sizeof(*H->cells)*size);

    for(unsigned int i = 0; i<size; i++)
    {
        H->cells[i].info = empty;
    }

    return H;

}

unsigned int
find(hash_table *H, const char *key)
{
    unsigned int index = hash1(key, H->size);
    unsigned int hash = hash2(key);
    unsigned max = index;

    while(H->cells[index].key!=key && H->cells[index].info!=empty)
    {
        index = (index+hash)%H->size;

        if(index==max){printf("Not found!"); return -1;}
        if(index>=H->size){index-=H->size;}

    }

    return index;
    

}

void
insert(hash_table *H, const char *key, const char *value)
{
    unsigned int index = find(H, key);

    if(H->cells[index].info!=legitimate)
    {

        H->cells[index].key= malloc(strlen(key)+1);
        H->cells[index].value = malloc(strlen(value)+1);


        strcpy(H->cells[index].key,key);
        strcpy(H->cells[index].value,value);

        H->cells[index].info = legitimate;

    }
}

void
dump(hash_table *H)
{
    for(unsigned int i = 0; i<H->size; i++)
    {   
        if(H->cells[i].info!=legitimate){continue;}

        printf("Index[%d]: %s\n", i, H->cells[i].value);
    }
}


int main()
{
    hash_table *H = initialize(10);
    insert(H,"name1","David");
    insert(H, "name2", "Radka");
    dump(H);
    return 0;
}

输出:

NO OUTPUT

我检查了 hash1()、hash2() 和 find() 函数是否正常工作,它们确实有效,检查了多个输入,一切似乎都正常工作。 我不确定缺少什么或我做错了什么。请帮忙。

【问题讨论】:

  • 很难回答您的问题,因为它不包含minimal reproducible example。请edit您的问题包括您的代码、示例输入和输出以及任何错误消息。告诉我们您期望发生的事情以及实际发生的事情。这将有助于我们更好地回答您的问题。
  • 你好像忘记在initialize()函数中初始化H-&gt;size了。
  • @JohnKugelman 谢谢,完成。
  • @MikeCAT 非常感谢!!!!
  • 你的意思是你故意让H-&gt;size 未初始化,如果你没有忘记的话?无论如何将其初始化为适当的值(不是零,因为它用于除法)。

标签: c data-structures hashtable double-hashing


【解决方案1】:

由于您的程序会生成核心转储,因此您可以利用它

运行你的程序,你得到

浮点异常(核心转储)

当进程意外终止时,它会生成一个包含进程内存内容的文件(崩溃时程序的快照)。由于核心文件创建默认是关闭的,我们使用ulimit命令来启用写入核心文件:

打开一个控制台,将进程资源限制设置为unlimited

ulimit -c unlimited

再次运行程序以生成核心文件

使用生成的核心文件启动调试器

> gdb demo core

Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x000055cd5fe03202 in hash1 (key=0x55cd5fe04024 "name1", size=0) at demo.c:35
35      return (hash%size);

它在hash1() 崩溃,让我们看看原因:

(gdb) print hash
$1 = 118636753
(gdb) print size
$2 = 0

你明白了!在return (hash%size);中除以零

hash1的原型是

unsigned int hash1(const char *key, unsigned int size);

检查谁在呼叫hash1()size 设置为 0:

(gdb) frame 1
#1  0x0000555555555309 in find (H=0x5555555592a0, key=0x555555556024 "name1") at demo.c:73
73      unsigned int index = hash1(key, H->size);

H-&gt;size 是罪魁祸首,它未初始化使用。

hash_table*
initialize(unsigned int size)
{
    hash_table *H = malloc(sizeof(*H));
    H->cells = malloc(sizeof(*H->cells)*size);

    for(unsigned int i = 0; i<size; i++)
    {
        H->cells[i].info = empty;
    }
    H->size = size; // Initialize it here
    return H;
}

【讨论】:

  • 非常感谢!虽然我不明白你的前两个步骤。 好的,打开控制台并将进程资源限制设置为无限制使用生成的核心启动调试器 如何、在何处以及为什么将其设置为无限制。演示内核到底是什么?
  • 我已经编辑了解释这些步骤的答案,我不知道您使用的是 Linux 还是某些 unix,在这种情况下您可以重现所有步骤,在 Windows 上您可以使用 MinGWgdb support
  • 谢谢!我花了一整夜安装 MinGW 并复习 gdp 的基础知识,现在它更有意义了。
  • 我想问一下,frame是做什么的,它是如何工作的?
猜你喜欢
  • 1970-01-01
  • 2011-12-25
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
相关资源
最近更新 更多