由于某些原因加上其他问题,代码似乎没有被释放

问题描述

所以不起作用的是,我从cs50课程check50收到了一条错误消息,它基本上告诉我它没有释放我的malloc。确切的消息如下:

程序没有内存错误 直到皱着眉头,才能检查

现在,我真的试图找出出什么问题了,但是它一直困扰着我一段时间,我不明白。现在输入代码https://hastebin.com/liluyaqubo.cpp就可以了。查看最后//部分(卸载字典)。我试图让valgrind工作,但没有,我可能没有。对于那些对我的工作感兴趣的人,就是这样的:https://cs50.harvard.edu/x/2020/psets/5/speller/ 一直让我发疯!

编辑:这是我编写的100多行代码: 关于该问题,似乎是有关内存未正确释放的某种情况。似乎超时了,因为cs50附带的调试器说直到皱着眉头才能翻倒,否则无法进行检查(又可以正常工作,很好)。

// Implements a dictionary's functionality
#include <stdbool.h>
#include <strings.h>
#include "dictionary.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.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 = 27;

// Hash table
node *table[N];

int wordcount = 0;

// Returns true if word is in dictionary else false
bool check(const char *word) {
    char lowercase[LENGTH + 1];
    for (int i = 0; i < LENGTH + 1; i++) {
        lowercase[i] = tolower(word[i]);
    }
    node *cursor = table[hash(lowercase)];
    while (cursor != NULL) {
        if (strcmp(lowercase,cursor->word) == 0) {
            return true;
        }
        cursor = cursor->next;
    }
    return false;
}

unsigned int hash(const char *word) {
    unsigned int h = 0;
    for (int i = 0,n = strlen(word + 1); i < n; i++)
        h = (h << 2) ^ word[i];
    return h % N;
}

// Loads dictionary into memory,returning true if successful else false
bool load(const char *dictionary) {
    FILE *file = fopen(dictionary,"r");
    if (file == NULL) {
        return false;
    }
    char word[LENGTH + 1];
    while (fscanf(file,"%s\n",word) != EOF) {
        node *tempNode = malloc(sizeof(node));
        if (tempNode == NULL) {
            return false;
        }
        //tempNode->next = NULL;
        strcpy(tempNode->word,word);
        if (table[hash(word)] == NULL) {
            tempNode->next = NULL;
            table[hash(word)] = tempNode;
        } else {
            tempNode->next = table[hash(word)];
            table[hash(word)] = tempNode;
        }
    }
    fclose(file);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void) {
    wordcount++;
    return wordcount;
}

// Unloads dictionary from memory,returning true if successful else false
bool unload(void) {
    for (int i = 0; i < N; i++) {
        node *tempNode = table[i];
        while (tempNode != NULL) {
            node *del = tempNode;
            tempNode = tempNode->next;
            free(del);
        }
        table[i] = NULL;
    }
    return true;
}

解决方法

您的unload()函数没有什么问题,它可以正确释放字典中的所有节点,并将哈希表重置为所有空指针。

相反,这是代码中的其他一些问题:

  • 将单词转为小写的循环遍历整个数组,但应在空终止符处停止。
  • 应将char的{​​{1}}参数强制转换为tolower(),以避免在已签名(unsigned char)的平台上对负值进行未定义的行为。
  • char应该将hash计算为n,而不是n = strlen(word)。更好的是:您应该将循环更改为:n = strlen(word + 1)
  • 在内存分配失败后,您应先关闭文件,然后再返回for (int i = 0; word[i] != '\0'; i++)
  • false格式fscanf的缺陷在于,字典中长于"%s\n"个字节的单词将导致目标数组溢出,从而导致未定义的行为。您可以使用长度修饰符来解决此问题:如果LENGTH被定义为"%15s",则LENGTH
  • 16停止返回fscanf()时,循环应停止。偶然地,这种特定的转换格式只能返回11,但是如果输入流中的下一个字符不能以数字开头,则EOF将返回"%d"
  • 0呼叫load() 4次相同的单词。您应该只计算一次哈希码并将其存储在本地变量中。
  • 不清楚函数hash()为什么增加全局变量size()