仅当在c中重新哈希表时,才对大小8进行无效读取

时间:2019-06-02 09:48:38

标签: c segmentation-fault hashtable

无效的读取发生在代码中我的HTSize函数中,但也发生在其他函数中。仅当哈希表被重新哈希时才发生此问题。这可能与我的HTCreate函数有关,但我不确定。

我尝试使用malloc和calloc,但没有任何效果。

typedef char* KeyType;
typedef int HTItem;
typedef struct node{
    KeyType key;
    HTItem item;
    struct node *next;
}List;
typedef struct {
    List *head;
}TableEntry;
typedef TableEntry *HTHash;


int TABLESIZE = 10;

HTHash HTCreate(void)
{
//malloc
//      int i;
//      HTHash table = (HTHash)malloc(TABLESIZE*sizeof(TableEntry));
//      for(i=0;i<TABLESIZE;i++)
//          table[i].head = NULL;
//      return table;
//calloc    
        return calloc(TABLESIZE, sizeof(TableEntry));
}

int HTSize(HTHash hash)
{
    int i,count=0;
    List *temp; 
    for(i=0;i<TABLESIZE;i++)
    {
        if(hash[i].head != NULL)
        {
            count++;
            temp = hash[i].head->next;
            while(temp != NULL)
           {
                count++;
                temp = temp->next;
           }
        }   
    }
    return count;   
}

void HTInsert(HTHash hash, KeyType key, HTItem item)
{
    float a = 0.0;
    int index = h(key);
    int i;
    List *NewNode = (List*)malloc(sizeof(List));
    NewNode->key = key;
    NewNode->item = item;
    NewNode->next = NULL;
    if(hash[index].head == NULL)
        hash[index].head = NewNode;
    else
    {
        if(!strcmp(hash[index].head->key,key))
            hash[index].head->item = item;
        else
        {
            while(hash[index].head->next != NULL)
            {
                if(!strcmp(hash[index].head->next->key,key))
                {
                    hash[index].head->next->item = 
item;
                    break;
                }
                hash[index].head->next = hash[index].head- 
>next->next;
            }
            if(hash[index].head->next == NULL)
                hash[index].head->next = NewNode;
        }
    }
    a = (1.0 * HTSize(hash))/ TABLESIZE;
    if(a>=0.9)
    {
        printf("hash table is rehashing!\n");
        HTRehash(hash); 
    }
}

void HTRehash(HTHash hash)
{
    int i;
    HTHash temp = hash;
    int n = TABLESIZE;
    TABLESIZE = 2 * TABLESIZE;
    hash = HTCreate();
    for(i=0;i<n;i++)
    {
        List* list = temp[i].head;
        while(list!=NULL)
        {
            HTInsert(hash,list->key,list->item);
            list = list->next;
        }
    }
}

在HTSize中使用valgrind运行它时,它会给出3次“无效的8号读数”。

1 个答案:

答案 0 :(得分:2)

您的问题似乎是用单个指针调用HTRehash。然后,您重新分配哈希表,但是现在您无法返回此新内存。

您必须使用双指针调用它,以便调用者可以使用新的内存,或者必须返回新的指针。后者在轮廓上更简单:

HTHash HTRehash(HTHash hash)
{
    //...
    hash = HTCreate();
    //...
    return hash;
}

我还注意到,您不会释放旧的哈希表。