【问题标题】:Hashtable leaking memory哈希表泄漏内存
【发布时间】:2018-06-12 15:07:41
【问题描述】:

我制作了一个哈希表,它运行良好,但是当我使用valgrind 运行它时,它告诉我在创建哈希表时存在内存泄漏,并且每次用户插入都会发生内存泄漏,每次插入 12 个字节,每次插入 40 个字节创建哈希表

这是一些可测试的代码:

#include <malloc.h>
#include <stdio.h>
#include "string.h"
#include "stdlib.h"
#define initial_size 5

typedef struct user_pos {
    char nick[6];
    int position_in_file;
}user_pos;

typedef struct bucket{
    user_pos *info;
}bucket;

typedef struct hashtable{
    int size;
    int elements;
    bucket **buckets;
}hashtable;


unsigned hash(char *s) {
    unsigned hashval;
    for (hashval = 0; *s != '\0'; s++)
        hashval = *s + 31*hashval;
    return hashval;
}

hashtable * create() {
    hashtable *htable;
    if((htable = malloc(sizeof(hashtable))) == NULL)
        return NULL;
    if((htable->buckets = malloc(sizeof(bucket) * initial_size)) == NULL)
        return NULL;
    htable->size = initial_size;
    htable->elements = 0;
    for(int i=0; i < initial_size; i++){
        htable->buckets[i] = NULL;
    }
    return htable;
}


void insert(hashtable *hashtable, char *nick, int position_in_file){
    int hash_value = hash(nick);
    int new_position = hash_value % hashtable->size;
    if (new_position < 0) new_position += hashtable->size;
    int position = new_position;
    while (hashtable->buckets[position] != NULL && position != new_position - 1) {
        if(hashtable->buckets[position]->info != NULL){
            position++;
            position %= hashtable->size;
        }else{
            break;
        }
    }
    hashtable->buckets[position] = malloc(sizeof(bucket));
    hashtable->buckets[position]->info = malloc(sizeof(user_pos));
    strcpy(hashtable->buckets[position]->info->nick, nick);
    hashtable->buckets[position]->info->position_in_file = position_in_file;
    hashtable->elements++;

}

void delete_hashtable(hashtable *ht) {
    for(int i = 0; i<ht->size; i++){
        if(ht->buckets[i] != NULL && ht->buckets[i]->info != NULL)
            free(ht->buckets[i]);
    }
    free(ht);
}

int main(){

    hashtable *ht = create();
    insert(ht, "nick1", 1);
    insert(ht, "nick2", 2);
    delete_hashtable(ht);

    return 0;
}

每次插入新项目时,我都会初始化一个存储桶,但我认为之后我无法释放它,因为这会擦除刚刚添加的内容,create() 函数也是如此。

在这种情况下如何避免内存泄漏?

提前致谢。

【问题讨论】:

  • 释放“ht->buckets”和“ht->buckets[i]->info”怎么样?
  • 您确定每个对应的malloc 都有一个free 吗?比如hashtable-&gt;buckets
  • 另外,valgrind 并没有告诉你代码中内存的分配位置,这应该会给你一个很好的线索来了解需要修复的内容
  • @ChrisTurner 是的,它告诉我它是我正在使用的 malloc,但如果我释放它们,插入中添加的信息将丢失

标签: c memory-leaks hashtable


【解决方案1】:

内存泄漏不在您的分配函数中,而是在清理中。您未能释放您在delete_hashtable 中分配的所有内容。

您清理了ht-&gt;buckets[i]ht,但未能清理ht-&gt;buckets[i]-&gt;infoht-&gt;buckets。您还需要释放它们:

void delete_hashtable(hashtable *ht) {
    for(int i = 0; i<ht->size; i++){
        if(ht->buckets[i] != NULL && ht->buckets[i]->info != NULL)
            free(ht->buckets[i]->info);
            free(ht->buckets[i]);
    }
    free(ht->buckets);
    free(ht);
}

另外,您为 htable-&gt;buckets 分配了错误的字节数:

if((htable->buckets = malloc(sizeof(bucket) * initial_size)) == NULL)

每个元素都是bucket *,而不是bucket,所以这是您应该使用的大小:

if((htable->buckets = malloc(sizeof(bucket *) * initial_size)) == NULL)

或者更好:

if((htable->buckets = malloc(sizeof(*htable->buckets) * initial_size)) == NULL)

这样,htable-&gt;buckets 的类型是什么或您以后是否更改它都无关紧要。

【讨论】:

  • 谢谢你的问题,以及代码的审查
  • 除了尺寸问题外,答案与我上面的评论相同。
猜你喜欢
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 2017-09-26
相关资源
最近更新 更多