我正在用 C 编写一个简单的程序,它根据在哈希表中查找单词来查找单词的字谜。我所拥有的是一个哈希表数组,其中单词按其长度索引,并通过其字母的总和在其中进行哈希处理,例如 a = 1、b = 2 等。
我仍然熟悉 C 中的动态内存管理,所以这个问题可能很简单,但我有一个函数可以为每个哈希表(及其内部数据)分配和取消分配内存。
我最初使用单个哈希表编写此程序,通过 valgrind 运行程序后,我发现内存已正确释放并且没有泄漏。然而,当扩展程序以使用哈希表数组时,valgrind 开始发现可能的泄漏(尽管它报告它们仍然可以访问)。我对为什么在哈希表数组中没有正确释放内存感到困惑,尽管数组中的每个哈希表都是通过最初使用的 deallocate 函数运行的。
完整代码的要点完整代码
typedef struct Bucket Bucket;
typedef struct HashTable HashTable;
struct Bucket {
char* data;
Bucket *next;
};
struct HashTable {
int size;
Bucket **buckets;
};
int main(int argc, char const *argv[])
{
// Allocate memory for array of hash tables
HashTable** hash_array = (HashTable**) malloc(sizeof(HashTable*) * WORD_SIZE);
for(i = 0; i < WORD_SIZE; i++) {
hash_alloc(&hash_array[i], BUCKET_COUNT);
}
// Main logic here...
// Free memory
for(i = 0; i < WORD_SIZE; i++) {
hash_dealloc(hash_array[i]);
}
free(hash_array);
return 0;
}
哈希表分配函数
void hash_alloc(HashTable** a, unsigned int size) {
*a = (HashTable*) malloc(sizeof(HashTable));
(*a)->buckets = (Bucket**) malloc(sizeof(Bucket*) * size);
(*a)->size = size;
}
哈希表释放函数
void hash_dealloc(HashTable* a) {
int i;
Bucket* current, *temp;
for(i = 0; i < a->size; i++) {
current = a->buckets[i];
while(current != NULL) {
temp = current;
free(temp->data);
current = current->next;
free(temp);
}
free(current);
}
free(a->buckets);
free(a);
}
添加到哈希表函数
void add_to_hash_array(HashTable** a, char* data) {
// Removed some other logic for readability...
replace_str(data, "\n", "\0");
newNode->data = strdup(data);
newNode->next = currentTable->buckets[index];
currentTable->buckets[index] = newNode;
} else {
return;
}
}
Valgrind 输出
==39817== 261,120 bytes in 128 blocks are still reachable in loss record 5 of 7
==39817== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==39817== by 0x400A38: hash_alloc (main.c:73)
==39817== by 0x4008B0: main (main.c:39)
==39817==
==39817== 286,936 bytes in 31,553 blocks are still reachable in loss record 6 of 7
==39817== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==39817== by 0x4EBAD71: strdup (strdup.c:43)
==39817== by 0x400D4D: add_to_hash_array (main.c:141)
==39817== by 0x400914: main (main.c:51)
==39817==
==39817== 504,848 bytes in 31,553 blocks are still reachable in loss record 7 of 7
==39817== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==39817== by 0x400D16: add_to_hash_array (main.c:136)
==39817== by 0x400914: main (main.c:51)