c - CS50 Speller.c 问题
问题描述
我对问题集 5 中的 CS50 拼写任务有一些问题。对于那些不熟悉这个问题的人,基本上我的程序用作拼写检查器(您插入字典和文本文件,程序会返回所有拼写错误的单词)。我们的任务是编写五个函数(check、hash、load、size、unload)。检查功能检查单词是否在集合字典中。Hash 基本上返回我用来根据文本中单词的输入组织单词的哈希表的数字索引。load 函数基本上将字典文件中的所有单词加载到哈希表中。size 函数返回字典的大小,最后 unload 函数释放分配给我的程序的所有内存。但是,当我使用 check50 测试我的程序时,内存释放显然存在错误。然而,我不
提前致谢!
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.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;
// Number of buckets in hash table
const unsigned int N = 26;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
int x = hash(word);
for (node *temp = table[x]; temp != NULL; temp = temp->next)
{
if (strcasecmp(word, temp->word) == 0)
{
return true;
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
char s = word[0];
if(word[0] < 97)
{
s = tolower(word[0]);
}
int index = s - 97;
return index;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// TODO
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
printf("Could not open dictionary.\n");
return false;
}
char theword[45];
while (fscanf(file, "%s", theword) != EOF)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
int wordlength = strlen(theword);
int x = hash(theword);
char tempword[45];
if (table[x] == NULL)
{
for (int j = 0; j < wordlength; j++)
{
n->word[j] = theword[j];
}
n->next = NULL;
table[x] = n;
}
for (node *temp = table[x]; temp != NULL; temp = temp->next)
{
node *temp2 = temp->next;
if (temp2 == NULL)
{
for (int k = 0; k < strlen(theword); k++)
{
n->word[k] = theword[k];
}
temp->next = n;
n->next = NULL;
}
}
}
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
int count = 0;
for (int i = 0; i < N; i++)
{
for (node *temp = table[i]; temp != NULL; temp = temp->next)
{
count++;
}
}
return count;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node *temp = table[i];
while (temp != NULL)
{
node *temp2 = temp->next;
free(temp);
temp = temp2;
}
}
return true;
}
解决方案
内存泄漏是由于未关闭 FILE 指针引起的,但您的代码还有另一个问题,即写入内存空间外部。以下是错误信息。这是调试和重现此错误的 [链接]。
Memory access warning: memory spaces are not freed; continue execution.
# 1 memory space is allocated at
# file:/musl-1.1.10/src/stdio/__fdopen.c::20, 10
# total 1164 bytes
#
Memory access error: writing to the outside of a memory space; abort execution.
# Writing 1 bytes to 0xffefc609 will clobber other memory-spaces.
#
# The memory-space-to-be-written (start:0xffefc5dc, size:45 bytes) is bound to 'theword' at
# file:/dictionary.c::57, 8
#
# 0xffefc5dc 0xffefc608
# +------------------------------+
# |the memory-space-to-be-written|......
# +------------------------------+
# ^~~~~~~~~~
# the write starts at 0xffefc609 that is right after the memory-space end.
#
# Stack trace (most recent call first) of the write.
# [0] file:/musl-1.1.10/src/stdio/vfscanf.c::271, 12
# [1] file:/musl-1.1.10/src/stdio/fscanf.c::28, 8
# [2] file:/dictionary.c::59, 10
# [3] file:/speller.c::40, 19
# [4] [libc-start-main]
Segmentation fault
推荐阅读
- powershell - 如何从 PowerShell 的目录输出中删除 FullName 标头
- react-native - 有没有办法在 React Native 中更改 DialogInput 中的键盘类型?
- r - R找到数据框列中最大值的索引
- javascript - JS中使用formdata和fetchAPI将表单上传的图片发送到服务器
- math - 表中值的插值
- java - 如何在控制器的方法中注入服务?
- sparse-matrix - 稀疏和复杂的广义特征值问题
- python - 如何使用 GOOGLE 作为 pandas 数据阅读器的数据源?
- bash - Git推送并行进程失败
- python - 根据条件将 Pandas 列中的文本拆分为不同的列