首页 > 解决方案 > 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;
}

标签: ccs50

解决方案


内存泄漏是由于未关闭 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

推荐阅读