我正在尝试使用 djb2 哈希算法解决这个 CS50 问题:https://cs50.harvard.edu/x/2024/psets/5/speller/。请参阅下面我的代码。运行代码所需的其他文件可以在上面提供的 CS50 链接中找到。我只对dictionary.c进行了更改,它包含在下面的代码中。
// Implements a dictionary's functionality
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
} node;
// TODO: Choose number of buckets in hash table
const unsigned int N = 100;
//Variable to count number of words loaded into dictionary
int count = 0;
// Hash table
node *table[N];
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO: Improve this hash function
unsigned long hash = 5381;
int c;
while((c = *word++))
{
hash = (((hash << 5) + hash) + c);
}
int hash_value = hash % N;
return hash_value;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
FILE *dict_file = fopen(dictionary, "r");
if (dict_file == NULL)
{
printf("Could not open %s.\n", dictionary);
return false;
}
for(int i = 0; i < N; i++)
{
table[i] = NULL;
}
char c;
int i = 0;
node *new_node = malloc(sizeof(node));
while (fread(&c, sizeof(char), 1, dict_file))
{
// printf("%c", c);
if(c != '\n')
{
new_node -> word[i] = c;
i++;
}
else
{
int key = hash(new_node -> word);
new_node -> next = table[key];
table[key] = new_node;
// printf("%lu", sizeof(node));
new_node = malloc(sizeof(node));
count++;
}
}
fclose(dict_file);
if(count > 0)
{
return true;
}
else
{
return false;
}
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
if(count > 0)
{
return count;
}
else
{
return 0;
}
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
for(int i = 0; i < N; i++)
{
node *temp_node = NULL;
while(table[i] != NULL)
{
temp_node = table[i] -> next;
free(table[i]);
table[i] = temp_node;
}
}
return false;
}
我看到错误- malloc():损坏的顶部大小 已中止(核心已转储)
根据我在网上阅读的内容,我认为损坏的顶部大小问题意味着在 malloc 调用中作为参数提供的大小无效。我的 malloc 调用位于 bool load 函数中,我使用 djb2 哈希算法将字典文件中的单词加载到哈希表中。我的函数循环遍历文件中的每个字符,直到形成一个单词并将其分配给哈希表中的节点,然后调用 malloc 分配一个等于节点大小的空间来存储下一个单词。
我使用调试工具和打印语句发现该函数在加载字典中的前十个单词时(直到 aardwolf)按预期工作,但在将 aardwolf 保存在哈希表中后调用 malloc 时显示上述错误。节点的大小是一个常量(56),所以我很困惑为什么这个大小突然对 malloc 无效。对于为什么会发生这种情况有什么想法吗?
循环中的 malloc 语句遇到问题可能有多种原因。 内存泄漏:
确保使用 free 函数释放由 malloc 分配的内存。未能释放内存可能会导致内存泄漏,导致程序每次迭代消耗越来越多的内存。
碎片:
如果在循环内分配和释放内存,随着时间的推移,内存可能会变得碎片化。这种碎片可能会导致后续分配的连续内存块不足。
内存大小不正确:
确保为数据分配正确的内存量。如果分配的内存不足,可能会导致内存损坏。 // 例子 int *ptr = (int *)malloc(num_elements * sizeof(int));