设计通用哈希

时间:2015-05-17 19:52:38

标签: c generics hash

我正在尝试实现一个通用的哈希结构,它可以支持任何类型的数据和任何哈希函数。

A编写代码并尝试运行它,它不起作用,它打破了。我尝试调试它并且在那里运行良好。我不知道问题出在哪里?

以下是我用于实现结构的代码:

“hash.h”文件:

typedef struct tip_hash_nod
{
    void *info;
    struct tip_hash_nod *urm;
}NOD_LISTA_HASH;

typedef struct
{
    NOD_LISTA_HASH *Table;
    int size;
    int sizeMemory;
    int (*hash)(const void *obiect,const int m);
    void (*distruge)(void *obiect);
}*HASH;

void initializare_hash(HASH *h,int size,int (*hash_dat)(const void *obiect,const int m),void (*distruge)(void *obiect));
int hash_insert(HASH *h,void *obiect,int sizeOfObiect);
int hash_search(HASH h,void *obiect,int (*compara)(const void *a,const void *b));
void hash_delete(HASH *h);

和“hash.c”文件:

void initializare_hash(HASH *h,int size,int (*hash_dat)(const void *obiect,const int m),void (*distruge)(void *obiect))
{
    int i;
    (*h) = (HASH)malloc(sizeof(HASH));
    (*h)->sizeMemory = size;
    if(size != 0)
    {
        (*h)->Table = (NOD_LISTA_HASH *)malloc((*h)->sizeMemory * sizeof(NOD_LISTA_HASH));
        for(i=0;i<(*h)->sizeMemory;i++)
        {
            (*h)->Table[i].info = NULL;
            (*h)->Table[0].urm = NULL;
        }
    }
    else
    {
        (*h)->Table = (NOD_LISTA_HASH *)malloc(sizeof(NOD_LISTA_HASH));
        (*h)->Table[0].info = NULL;
        (*h)->Table[0].urm = NULL;
        (*h)->sizeMemory = 1;
    }
    (*h)->size = 0;
    (*h)->hash = hash_dat;
    (*h)->distruge = distruge;
}
int hash_insert(HASH *h,void *obiect,int sizeOfObiect)
{
    int i,poz;
    NOD_LISTA_HASH *p;
    if((*h)->size == (*h)->sizeMemory)
    {
        HASH h1;
        initializare_hash(&h1,2*(*h)->sizeMemory,(*h)->hash,(*h)->distruge);
        for(i=0;i<(*h)->sizeMemory;i++)
        {
            if((*h)->Table[i].info != NULL)
                hash_insert(&h1,(*h)->Table[i].info,sizeOfObiect);
            p=(*h)->Table[i].urm;
            while(p!=NULL)
            {
                hash_insert(&h1,p->info,sizeOfObiect);
                p = p->urm;
            }
        }
        hash_delete(h);
        *h=h1;
        return hash_insert(h,obiect,sizeOfObiect);
    }
    else
    {
        poz = (*h)->hash(obiect,(*h)->sizeMemory);
        if((*h)->Table[poz].info == NULL)
        {
            (*h)->Table[poz].info = malloc(sizeOfObiect);
            memcpy((*h)->Table[poz].info,obiect,sizeOfObiect);
            (*h)->Table[poz].urm = NULL;
            (*h)->size++;
        }
        else
        {
            p = &((*h)->Table[poz]);
            while(p->urm!=NULL)
                p = p->urm;
            p->urm = (NOD_LISTA_HASH *)malloc(sizeof(NOD_LISTA_HASH));
            p = p->urm;
            p->info = malloc(sizeOfObiect);
            memcpy(p->info,obiect,sizeOfObiect);
            p->urm = NULL;
        }
        return poz;
    }
}

int hash_search(HASH h,void *obiect,int (*compara)(const void *a,const void *b))
{
    int poz;
    NOD_LISTA_HASH *p;
    poz = h->hash(obiect,h->sizeMemory);
    if(h->Table[poz].info == NULL)
        return -1;
    else
        if(compara(h->Table[poz].info,obiect)==0)
            return poz;
        else
        {
            p=h->Table[poz].urm;
            while(p != NULL)
            {
                if(compara(p->info,obiect)==0)
                    return poz;
                p = p->urm;
            }
            return -1;
        }
}

static void distruge_lista(NOD_LISTA_HASH *p,void (*distruge_obiect)(void *obiect))
{
    if(p->urm != NULL)
        distruge_lista(p->urm,distruge_obiect);
    else
    {
        if(p->info != NULL)
            distruge_obiect(p->info);
        free(p);
    }
}

void hash_delete(HASH *h)
{
    int i;
    for(i=0;i<(*h)->sizeMemory;i++)
    {
        if((*h)->Table[i].info != NULL && (*h)->Table[i].urm != NULL)
        {
            distruge_lista((*h)->Table[i].urm,(*h)->distruge);
        }
    }
    free((*h)->Table);
    *h = NULL;
}

这是我的“main.c”文件:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "hash.h"

int comparare(const void *a,const void *b)
{
    return (*(int *)a - *(int *)b);
}

int hash(const void *obiect,int m)
{
    return (*(int *)obiect) % m;
}

void distruge_obiect(void *obiect)
{
    free((int *)obiect);
}

int main()
{
    HASH h;
    int val,error;

    initializare_hash(&h,0,hash,distruge_obiect);

    val = 20;
    hash_insert(&h,&val,sizeof(int));
    val = 800;
    hash_insert(&h,&val,sizeof(int));
    val = 2000;
    hash_insert(&h,&val,sizeof(int));
    val = 765;
    hash_insert(&h,&val,sizeof(int));

    val = 800;
    error = hash_search(h,&val,comparare);
    if(error == -1)
        printf("Elementul %d nu se afla in hash.\n",val);
    else
        printf("Elementul %d se afla pe pozitia: %d.\n",val,error);
    hash_delete(&h);

    getch();

    return 0;
}

如果我尝试调试它已经很难过没有问题,但是当我运行它时,它会崩溃。我可以假设它不能处理内存或其他东西。我的调用堆栈就像这样: call stack

1 个答案:

答案 0 :(得分:1)

你已经在我们身上丢掉了一大堆代码,没有太多可以继续下去。无论如何我快速浏览了一下,注意到这个错误的分配:

(*h) = (HASH)malloc(sizeof(HASH));

HASH是指针类型,因此您只为一个指针分配足够的内存。您想为其指向的事物分配内存:

*h = malloc(sizeof(**h));

(在C中不需要演员表,这里的一些人会因为不使用演员而尖锐。)

该错误完全足以导致各种不良行为。特别是,错误的代码似乎可以工作,直到你动态分配更多的内存并写入,所以这或许可以解释为什么你的测试在第二次插入时崩溃。