1

我正在实现一个具有 remove_entry 函数和 clear_table 函数的哈希表。现在我收到与 remove_entry 函数有关的内存读取错误。帮助将不胜感激

这些是我的结构:

typedef struct bucket {
   char *key;
   void *value;
   struct bucket *next;
} Bucket;

typedef struct {
   int key_count;
   int table_size;
   void (*free_value)(void *);
   Bucket **buckets;
} Table;

这是我的功能:

int remove_entry(Table * table, const char *key){
    unsigned int hc = 0;
    Bucket *curr_b;
    Bucket *next_b;

    if(table == NULL || key == NULL){
        return FAIL;
    } else {
        hc = hash_code(key)%(table->table_size);
        if(table->buckets[hc] != NULL){
            curr_b = table->buckets[hc];

            /*Check the buckets in linked list*/
            while(curr_b != NULL){
                next_b = curr_b->next;

                if(strcmp(curr_b->key,key) == 0){
                    free(curr_b->key);
                    if(table->free_value != NULL){
                        table->free_value(curr_b->value);
                    }
                    free(curr_b);
                    curr_b = NULL;
                    table->key_count--;
                    return SUCC;
                } else {
                    curr_b = next_b;
                }
            }
            return FAIL;
        }
        return FAIL;
    }
}

内存泄漏发生在删除条目并尝试读取表之后。我不认为我删除了正确的东西。

内存错误:

不知道如何从终端复制/粘贴,所以他们都说

Invalid read of size __
Address ____ is __ bytes inside a block of size ___ free'd
4

1 回答 1

1

您需要考虑table->buckets[hc]您空闲的桶在哪里的情况。

在添加之前free(curr_b->key);

if(curr_b == table->buckets[hc]) {
    table->buckets[hc] = next_b;
}

就像现在一样,你释放了一个桶,但table->buckets[hc]仍然指向它。因此,下次您阅读它时,您正在阅读已释放的内存。因此错误。

此外,您需要跟踪前一个存储桶,以便在删除存储桶时将前一个存储桶指向下一个存储桶。

于 2013-10-27T16:53:12.287 回答