【问题标题】:what is wrong with this flushing function for hash table?这个哈希表的刷新函数有什么问题?
【发布时间】:2020-07-05 02:59:57
【问题描述】:

我在刷新整个哈希表时遇到了一个奇怪的问题。 数据结构如下:

typedef struct data_entry_{
    char data[32];
    struct data_entry_ *next;
}data_entry_t;

typedef struct table_entry_{
    char hash[32];
    struct data_entry_ *next_data;
    struct table_entry_ *next_hash;
}table_entry_t;

typedef struct table_{
    table_entry_t *next;
}table_t;

在主函数中,我用下面的函数初始化表

table_t *init(){
    table_t *table = calloc(1, sizeof(table_t));
    table_entry_t *node = calloc(1, sizeof(table_entry_t));
    node->next_hash = NULL;
    node->next_data = NULL;
    strcpy(node->hash, "NULL"); 
    table->next = node;
    return table;
}

使用以下函数将数据添加到表中:

int add(table_t *table, char *data){
    table_entry_t *head = table->next;
    table_entry_t *prev;
    char hash[32];
    hash_function(data, hash);

    if(!strcmp(head->hash, "NULL")){ 
        data_entry_t *item = calloc(1, sizeof(data_entry_t));
        strcpy(item->data, data);
        item->next = NULL;
        strcpy(head->hash, hash);
        head->next_data = item;
        head->next_hash = NULL;
        return 0;
    }
    while(head){
        if(!strcmp(head->hash, hash)){
            data_entry_t *temp = head->next_data;
            data_entry_t *previous;
            while(temp){
                if(!strcmp(temp->data, data)){
                    printf("data exists\n");
                    return 0;
                }
                previous = temp;
                temp = temp->next;
            }
            data_entry_t *item = calloc(1, sizeof(data_entry_t));
            strcpy(item->data, data);
            item->next = NULL;
            previous->next = item;
            return 0;
        }
        prev = head;
        head = head->next_hash;
    }

    table_entry_t *pack = calloc(1, sizeof(table_entry_t));
    data_entry_t *item = calloc(1, sizeof(data_entry_t));
    strcpy(pack->hash, hash);
    strcpy(item->data, data);
    item->next = NULL;
    pack->next_data = item;
    prev->next_hash = pack;
    return 0;
}

问题出在这个函数上:

int flush(table_t *table){
    table_entry_t *head = table->next;
    table_entry_t *temp;
    data_entry_t *current, *previous; 
    if(head->next_data == NULL){
        printf("table is empty\n");
        return -1;
    }
    strcpy(head->hash, "NULL");
    while(head){
        current = head->next_data;
        while(current){
            previous = current;
            current = current->next;
            free(previous);
        }
        temp = head;
        head = head->next_hash;
        free(temp);
    }  
    return 0;
}

在调用flush之后,当我想显示表格时,我希望看到“表格为空”,但显然这个函数不会释放任何节点。如果有人帮助我,我真的很感激。

【问题讨论】:

  • 您希望在刚刚释放的指针中看到什么值?提示,它不是 NULL。
  • 我应该看到 NULL 值
  • 不。在 free() 上阅读文档。
  • free() 返回无效。我应该怎么做才能使节点为NULL?
  • 问题 1. 如果您提前返回,所有这些指针(温度、头、当前、上一个)都不会释放。

标签: c linked-list hashtable


【解决方案1】:

你希望一个被释放的指针得到 NULL 值。
然而这是不可能的,因为free() 只接收指针内部的值,而不是地址,即不是指向指针的指针。

您的代码假定此处释放的指针为 NULL:

if(head->next_data == NULL){

但是,只有将 NULL 值写入指针时才会出现这种情况。

有些代码看起来很相似,strcpy(head->hash, "NULL");,但我相信您不会期望将非字符串值 NULL 写入指针。

您可以通过自己编写来确保之后释放的所有指针都包含 NULL。靠近这个free(previous);。然而,有必要将 NULl 写入链表中的实际指针 - 而不是例如到变量previous。您可以使用存储在该变量中的指针副本进行释放,但不能覆盖原始指针。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 2015-10-25
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
相关资源
最近更新 更多