我是CS新手,可以在拼写pset上真正使用一些帮助。我有一个基本的轮廓,似乎没有错误,但是我仍然有问题。它在check50中失败:
如果我通过它运行一个测试器文件,则计数器仅显示字典中有2个单词,因此它会吐出文档中几乎每个单词都拼写错误(导致我认为加载有错误,但我不知道在哪里。
还有一个valgrind错误。它显示以下内容:
堆摘要:在退出时使用:14个块中的1,300字节。 堆总使用量:15个分配,1个释放,5406个字节分配。
任何帮助将不胜感激;我已经坚持了三天!
#include <stdbool.h>
#include <string.h>
#include <strings.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;
// 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 numloc = hash(word);
node *cursor = table[numloc];
while (cursor != NULL)
{
if (strcasecmp(cursor->word, word) == 0)
{
return true;
}
cursor = cursor->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
unsigned long hash = 5381;
int c;
while ((c = *word++))
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash % N;
}
// Loads dictionary into memory, returning true if successful else false
int counter = 0;
bool load(const char *dictionary)
{
FILE *dictionary = fopen(dictionary, "r");
if (dictionary == NULL)
{
return false;
}
char tempword[LENGTH + 1];
for (int i = 0; i < N; i++)
{
table[i] = NULL;
}
while (fscanf(dict, "%s", tempword) != EOF)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
strcpy(n->word, tempword);
int A = hash(tempword);
if (table[A] == NULL)
{
table[A] = n;
n->next = NULL;
}
else
{
n->next = table[A];
table[A] = n;
}
counter++;
}
fclose(dictionary);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (counter == 0)
{
unload();
return 1;
}
else
{
return counter;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node *cursor = table[i];
node *tmp = table[i];
while (cursor != NULL)
{
cursor = cursor->next;
free(tmp);
tmp = cursor;
}
return true;
}
return false;
}
答案 0 :(得分:0)
dictionary.h
的内容是什么?照原样,发布的代码无法编译!
以下是通过编译器运行的结果,其中包含有关如何解决问题的一些建议。
编译语句:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o"
编译器的输出消息:
untitled1.c:20:7: error: variably modified ‘table’ at file scope
20 | node *table[N];
| ^~~~~
this is not C++.. Therefore suggest replacing:
const unsigned int N = 26;
使用
#define N 26
因此表[[]将被正确声明
untitled1.c: In function ‘check’:
untitled1.c:25:18: warning: implicit declaration of function ‘hash’ [-Wimplicit-function-declaration]
25 | int numloc = hash(word);
| ^~~~
在代码的这一点上,编译器不知道函数hash()
的原型。建议将hash()
函数移到包含此语句的函数之前。
untitled1.c: At top level:
untitled1.c:39:14: error: conflicting types for ‘hash’
39 | unsigned int hash(const char *word)
| ^~~~
untitled1.c:25:18: note: previous implicit declaration of ‘hash’ was here
25 | int numloc = hash(word);
| ^~~~
untitled1.c: In function ‘hash’:
untitled1.c:45:37: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
45 | hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
| ^
请勿将局部变量命名为与函数名称相同的名称。在上述情况下,编译器认为代码是递归调用函数:hash()
untitled1.c:47:17: warning: conversion from ‘long unsigned int’ to ‘unsigned int’ may change value [-Wconversion]
47 | return hash % N;
| ~~~~~^~~
untitled1.c: In function ‘load’:
untitled1.c:54:11: error: ‘dictionary’ redeclared as different kind of symbol
54 | FILE *dictionary = fopen(dictionary, "r");
| ^~~~~~~~~~
dictionary
已被声明为字符串。因此,请在此处使用其他一些变量名。
untitled1.c:52:23: note: previous definition of ‘dictionary’ was here
52 | bool load(const char *dictionary)
| ~~~~~~~~~~~~^~~~~~~~~~
untitled1.c:54:30: warning: passing argument 1 of ‘fopen’ from incompatible pointer type [-Wincompatible-pointer-types]
54 | FILE *dictionary = fopen(dictionary, "r");
| ^~~~~~~~~~
| |
| FILE * {aka struct _IO_FILE *}
In file included from untitled1.c:4:
/usr/include/stdio.h:246:14: note: expected ‘const char * restrict’ but argument is of type ‘FILE *’ {aka ‘struct _IO_FILE *’}
246 | extern FILE *fopen (const char *__restrict __filename,
| ^~~~~
untitled1.c:60:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
60 | for (int i = 0; i < N; i++)
|
^
不比较有符号和无符号值。它“可能”有效,但是您不能依靠它起作用。
untitled1.c:64:19: error: ‘dict’ undeclared (first use in this function)
64 | while (fscanf(dict, "%s", tempword) != EOF)
| ^~~~
dict
的类型必须为FILE *
,但是从未通过调用fopen()
untitled1.c:64:19: note: each undeclared identifier is reported only once for each function it appears in
untitled1.c:72:17: warning: conversion to ‘int’ from ‘unsigned int’ may change the sign of the result [-Wsign-conversion]
72 | int A = hash(tempword);
| ^~~~
untitled1.c: In function ‘size’:
untitled1.c:100:16: warning: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
100 | return counter;
| ^~~~~~~
untitled1.c: In function ‘unload’:
untitled1.c:107:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
107 | for (int i = 0; i < N; i++)
| ^
Compilation failed.
答案 1 :(得分:0)
内存泄漏的原因是,在卸载的最后一步,您还没有释放最后一个节点。试用这个版本的while循环。您希望将free(temp)作为循环的最后一行,以便在游标= NULL时不会初始化/占用内存
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node *cursor = table[i];
while (cursor != NULL)
{
node *tmp = cursor;
cursor = cursor->next;
free(tmp);
}
free(cursor);
return true;
}
return false;
}