c - 由于某种原因以及其他问题,代码似乎没有被释放
问题描述
所以不起作用的是我从 cs50 课程 check50 收到一条错误消息,它基本上告诉我它没有释放我的 malloc。确切的消息如下:
程序没有内存错误无法检查,直到皱眉倒转
现在我真的试图找出问题所在,但它一直困扰着我一段时间,我不明白。现在获取代码:https ://hastebin.com/liluyaqubo.cpp这有它。查看最后//
一部分(卸载字典)。我试图让 valgrind 工作,但它没有,我可能没有它。对于那些对我正在做的事情感兴趣的人,这是:https ://cs50.harvard.edu/x/2020/psets/5/speller/
这让我发疯了!
编辑:这是我写的 100 多行代码:关于这个问题,似乎是关于内存没有被正确释放的问题。它似乎超时了,因为 cs50 附带的调试器说它无法检查,直到皱眉倒转(AKA 它可以工作并且很好)。
// 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
在签名的平台上对负值进行未定义的行为。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"
ifLENGTH
定义为16
. - 当
fscanf()
停止返回时,循环应该停止1
。碰巧这种特定的转换格式只能返回1
orEOF
,但如果输入流中的下一个字符不能以数字开头,"%d"
则会返回。0
load()
hash()
为同一个词调用4 次。您应该计算一次哈希码并将其存储在局部变量中。- 尚不清楚为什么函数会
size()
增加全局变量wordcount
。
推荐阅读
- c# - 如何将动态模型作为“T”传递给 C# 泛型函数
- node.js - 如何通过 AWS lambda nodejs 函数索引存储在 S3 中的 XML 文件?
- php - RSA:从 Python 中的 n 和 e 生成公钥,PHP 给我两个不同的公钥
- influxdb - 为什么任何用户都可以登录influxdb?
- python-3.x - Boto3:获取所有可用 S3 存储桶详细信息的详细信息
- angular - 添加 LazyLoad - 'mat-icon' 不是已知元素
- reactjs - 更新依赖于 React-Hooks 中其他计算状态的状态
- django - 使用 Docker Container - Django 构建后维护媒体文件
- automation - 有没有办法让测试让它的 TestCaseSource 从外部源(如 excel)读取数据?
- node.js - npm 开始显示 index.html 未定义,尽管 index.html 存在