【问题标题】:Hash table memory leak哈希表内存泄漏
【发布时间】:2014-09-25 05:28:07
【问题描述】:

我有一个基本的哈希表实现,当我运行它时,一切都很好,但是 valgrind 说我失去了一些记忆。

==11454== HEAP SUMMARY:
==11454==     in use at exit: 136 bytes in 1 blocks
==11454==   total heap usage: 10 allocs, 9 frees, 224 bytes allocated
==11454== 
==11454== LEAK SUMMARY:
==11454==    definitely lost: 136 bytes in 1 blocks
==11454==    indirectly lost: 0 bytes in 0 blocks
==11454==      possibly lost: 0 bytes in 0 blocks
==11454==    still reachable: 0 bytes in 0 blocks
==11454==         suppressed: 0 bytes in 0 blocks

我认为这可能是由于我为键指针分配内存的方式。这是我的代码 表:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "htable.h"
#include "mylib.h"

struct htablerec {

  int capacity;
  int num_keys;
  char **keys;

};

static unsigned int htable_word_to_int(char *word) {
  unsigned int result = 0;
  while (*word != '\0') {
    result = (*word++ + 31 * result);
  }
  return result;
}

static unsigned int htable_hash(htable h, unsigned int i_key) {
  return i_key % h->capacity;
}

htable htable_new(int capacity) {

  int i;
  htable result = emalloc(sizeof *result);
  result->capacity = capacity;
  result->num_keys = 0;
  result->keys = emalloc(capacity * sizeof result->keys[0]);

  for (i = 0; i < capacity; i++) {

    result->keys[i] = NULL;
  }

  return result;
}

void htable_free(htable h) {

  int i;
l

  for (i = 0; i < h->capacity; i++) {

    free(h->keys[i]);
  }

  free(h);
}

int htable_insert(htable h, char *key) {

  unsigned int index = htable_word_to_int(key) % h->capacity;

  if (h->num_keys == h->capacity) {
    return 0;
  }
  for (;;) {

    if (NULL == h->keys[index]) {

      h->keys[index] = emalloc(sizeof(key));
      strcpy(h->keys[index], key);
      h->num_keys++;

      return 1;
    }
    if (strcmp(h->keys[index], key) == 0) {

      return 1;
    }
    index = htable_hash(h, index + 1);
  }
}

void htable_print(htable h, FILE *stream) {

  int i;

  for (i = 0; i < h->capacity; i++) {
    fprintf(stream, "%2d %s\n", i, h->keys[i] == NULL ? "" : h->keys[i]);
  }
}

emalloc 函数只是使用 malloc 并检查它是否正确分配了内存。另外,在我的 插入函数,我 emalloc 键的大小。但是 key 是一个指针,所以不应该给我大小 不是单词的指针?

【问题讨论】:

  • Valgrind 可能会告诉您使用--leak-check=full 重新运行它,以了解泄漏内存的分配位置。这样做。
  • 顺便说一句,h-&gt;keys[index] = emalloc(sizeof(key)); 不对。既然你在它之后调用strcpy,你应该使用h-&gt;keys[index] = emalloc(strlen(key)+1);

标签: c memory-leaks hashtable


【解决方案1】:

“我认为这可能是由于我将内存分配给我的键指针的方式。”

实际上,您正确分配了键指针。缺少free()ing 似乎是你的失败:

result->keys = emalloc(capacity * sizeof result->keys[0]);

需要在某处free()ed。如:

void htable_free(htable h) 
{
   int i;
   for (i = 0; i < h->capacity; i++)
   {
       free(h->keys[i]);
   }
   free(h->keys); // NOTE: h->keys freed here.
   free(h);
}

【讨论】:

  • 嘿,谢谢,完全错过了。在我的 for 循环中,我不太清楚为什么我用 sizeof key 而不是 sizeof *key 来分配它。 sizeof *key 不是给出实际 char 数组的大小吗?
  • @Paldan 您的分配是正确的。它说“给我能够容纳capacity 的项目数量的内存,这些项目的大小与我的keys 成员持有的东西一样大”。注意:emalloc(capacity * sizeof *(result-&gt;keys)); 也可以。
  • 嘿,谢谢,我意识到你提到的部分是正确的,但我对插入函数中无限 for 循环中的部分更加困惑(我应该更具体)。跨度>
  • @Paldan 是的,好的。我明白你现在的意思了。该for循环应该只运行到最大容量,如果达到,扩展表,通过散列函数发送当前内容,然后重复链接过程。很确定这是你的任务的一部分,但你正确地指出,如果不加以检查,无限循环最终可能会超过你的链,并且你不断地堆积数据。它应该被解决,你的直觉还不完整。
猜你喜欢
  • 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
相关资源
最近更新 更多