无法弄清楚这段代码有什么问题以及为什么我会收到此错误。 c:106 是我标记的行。我认为问题出在上一行的空检查中的 n 值。 这意味着从表中传递的任何内容都是问题?我认为。 第二个函数是加载表的地方。但没有看到任何问题。 刚刚丢了。
==6929== Conditional jump or move depends on uninitialised value(s)
==6929== at 0x4012C1: unload (dictionary.c:106)
==6929== by 0x400E09: main (speller.c:152)
==6929== Uninitialised value was created by a heap allocation
==6929== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6929== by 0x4011B5: load (dictionary.c:71)
==6929== by 0x400964: main (speller.c:40)
==6929==
// 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 = 676;
// Hash table
node *table[N];
int wc = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char c[LENGTH + 1];
node *n =table[hash(word)];
while (n != NULL)
{
if (strcasecmp(n->word, word) ==0)
{
return true;
}
n = n->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
int tally = 0;
int j = 0;
while (word[j] != '\0')
{
char letter = tolower(word[j]);
tally += letter - 'a';
j++;
}
return tally % N;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *f = fopen(dictionary, "r");
if(f == NULL)
{
return false;
}
char t[LENGTH + 1];
while(fscanf(f, "%s\n", t) != EOF)
{
node *n = NULL;
n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
strcpy(n->word, t);
int x = hash(t);
if (table[x] == NULL)
{
table[x] = n;
}
else
{
n->next = table[x];
table[x] = n;
}
wc++;
}
fclose(f);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return wc;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
node *n = NULL;
for (int i = 0; i < N; i++)
{
n = table[i];
while(n != NULL )
{
node *x = n;
n = n->next;
free(x);
}
table[i] = NULL;
}
free(n);
return true;
}
当 valgrind 说错误位于特定行时,有时它实际上可能位于上一行或下一行。
这里就是这种情况。在第 105 行,有
n != NULL
行。 n
尚未初始化,因此您有未定义的行为。请检查 table
是如何初始化的(代码中未显示)。
最可能导致错误的原因是:您对数组进行了 malloc 但尚未对其进行初始化,或者将值初始化为
X<N
,然后从索引 0
到 N
访问数组,导致访问不正确对于]X,N]
。
编辑:更新代码后,很明显它至少包含以下问题:
table
通过循环 while(fscanf(f, "%s\n", t) != EOF)
进行初始化。 = 但用 while(fscanf(f, "%s\n", t) != EOF)
解析。假设您的领域中有 X 领域,如果 X<N
呢? X>N
?if (table[x] == NULL){table[x] = n;}
table[x]->next
仍未初始化我应该对表使用 calloc 吗?
这是有可能的。但您也可以通过使用 malloc 正确初始化数组来使其工作。两种可能性都是可行的。
总的来说,我认为您的代码不必要地复杂,可以大大简化。您可能想要重构它,而不仅仅是纠正错误。
以下建议代码:
现在是拟议的代码;
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#define LENGTH 50
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table
#define N 676
// Hash table
node *table[N] = {NULL};
unsigned wc = 0;
// Hashes word to a number
unsigned int hash(const char *word)
{
unsigned tally = 0;
int j = 0;
while (word[j] != '\0')
{
int letter = tolower(word[j]);
tally += (unsigned)letter - 'a';
j++;
}
return tally % N;
}
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// char c[LENGTH + 1];
node *n =table[hash(word)];
while (n != NULL)
{
if (strcasecmp(n->word, word) ==0)
{
return true;
}
n = n->next;
}
return false;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *f = fopen(dictionary, "r");
if(f == NULL)
{
return false;
}
char t[ LENGTH + 1 ];
while( fscanf( f, "%49s", t ) == 1 )
{
node *n = NULL;
n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
strcpy( n->word, t );
unsigned x = hash(t);
if (table[x] == NULL)
{
table[x] = n;
}
else
{
n->next = table[x];
table[x] = n;
}
wc++;
}
fclose(f);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return wc;
}
// Unloads dictionary from memory, returning true if successful else false
void unload(void)
{
for ( unsigned i = 0; i < N; i++)
{
node *n = table[i];
while(n != NULL )
{
node *x = n;
n = n->next;
free(x);
}
table[i] = NULL;
}
//free( table );
//return true;
}
您在代码中的某处创建了一个指针,但未初始化 要解决这个问题,你必须给指针一个初始值,甚至是NULL。
比如我代码中的load函数如下:
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// Open dictionary
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
return false;
}
// Navigate dictionary word by word
char word[LENGTH + 1];
while (fscanf(file, "%s", word) == 1)
{
// Initialize new node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
// Free other nodes in table
unload();
return false;
}
// Set word of new node
strcpy(new_node->word, word);
// Calculate hash code of word
int hash_code = hash(word);
// Check first node of hash table
if (table[hash_code] == NULL)
{
table[hash_code] = new_node;
new_node->next = NULL;
word_count++;
}
else
{
new_node->next = table[hash_code];
table[hash_code] = new_node;
word_count++;
}
}
// Close dictionary file
fclose(file);
return true;
}
注意 if(table(hash_code) == NULL) 语句。 我new_node->next = NULL;我添加了。