正在通过valgrind发现“仍然可以到达”的内存泄漏。我读过“仍然可以到达”的泄漏通常不是问题,但是我希望代码完美无缺,而且泄漏8,012,816字节似乎很多。代码和valgrind结果如下。
我尝试释放您可以想象的所有内容(fclose file
,free malloc
,global variables
,nodes
),然后绕圈转。我假设问题出在加载或卸载函数,更可能是后者,因为我不确定是否要删除所有哈希表节点以及链接列表节点。也许我创建了太多的NULL节点,因为它们是NULL而没有被释放?当我将哈希表大小(N)更改为1时,没有泄漏,但是它是一个只有1个链表的无用哈希表!当前N是任意的26 x 26 x 26-不知道这应该是什么,或者是否有一种计算最优值的方法?感谢您的帮助!
// Implements a dictionary's functionality
#include <stdbool.h> // bools
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h> // string case compare
#include <string.h> // strings
#include <ctype.h> // upper/lowercase
#include "dictionary.h"
int word_count = 0; // Counts words as they are loaded into hashtable by the load function below.
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 17576;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
int key = hash(word);
node* cursor = table[key];
while(cursor != NULL)
{
if(strcasecmp(cursor -> word, word) == 0)
{
return true;
}
cursor = cursor -> next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
unsigned int hash = 0;
for (int i = 0 ; word[i] != '\0' ; i++)
{
hash = 31*hash + tolower(word[i]);
}
return hash % N;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE* file = fopen(dictionary, "r");
if(file == NULL)
{
fclose(file);
return false;
}
// Initialise hashtable buckets
for(int i = 0; i < N; i++)
{
table[i] = NULL;
}
// Read every word until end of file and makes copy to temp_node
char temp_word[LENGTH +1];
while(fscanf(file, "%s\n", temp_word) != EOF)
{
node* temp_node = malloc(sizeof(node));
if(temp_node == NULL)
{
return false;
}
strcpy(temp_node -> word, temp_word);
int k = hash(temp_word);
if(table[k] == NULL)
{
temp_node -> next = NULL;
table[k] = temp_node;
}
else
{
temp_node -> next = table[k];
table[k] = temp_node;
}
word_count++;
}
fclose(file);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return word_count;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
node* cursor = NULL;
for(int i = 0; i < N; i++)
{
cursor = table[i];
while(cursor != NULL)
{
node* temp = cursor;
cursor = cursor -> next;
free(temp);
}
return true;
}
return false;
}
**
HEAP SUMMARY:
in use at exit: 8,012,816 bytes in 143,086 blocks
total heap usage: 143,096 allocs, 10 frees, 8,023,416 bytes allocated
8,012,816 bytes in 143,086 blocks are still reachable in loss record 1 of 1
at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4011F3: load (dictionary.c:83)
by 0x400964: main (speller.c:40)
LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 8,012,816 bytes in 143,086 blocks
suppressed: 0 bytes in 0 blocks
For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)**