Cs50 Speller 未初始化值是由堆分配错误创建的
Cs50 Speller Uninitialised value was created by a heap allocation error
我有一些代码应该获取字典文件,读取每个单词并将其添加到 trie 数据结构中,在单词的最后一个节点上将 bool 设置为 true。
它可以运行,但是当我稍后在 check() 函数中对照字典检查单词时,它总是说错误。
Valgrind 抛出此错误;
==20700==
==20700== Conditional jump or move depends on uninitialised value(s)
==20700== at 0x40116F: load (dictionary.c:114)
==20700== by 0x400834: main (speller.c:40)
==20700== Uninitialised value was created by a heap allocation
==20700== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20700== by 0x401180: load (dictionary.c:116)
==20700== by 0x400834: main (speller.c:40)
==20700==
Killed
我环顾四周并添加了循环遍历 children[] 并在创建新节点后初始化为 NULL,但似乎仍然存在问题。
// Represents a node in a trie
typedef struct node
{
bool is_word;
struct node *children[N];
}
node;
// Represents a trie
node *root;
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Initialize trie
root = malloc(sizeof(node));
if (root == NULL)
{
return false;
}
root->is_word = false;
for (int i = 0; i < N; i++)
{
root->children[i] = NULL;
}
// Open dictionary
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
unload();
return false;
}
//declare pointer to store adress of current node
node *ptr = root;
// Buffer for a word
char word[LENGTH + 1];
for (int i = 0; i < LENGTH + 1; i++)
{
word[i] = 0;
}
int size = 0;
// Insert words into trie
while (fscanf(file, "%s", word) != EOF)
{
// make pointer to current place in trie structure and intitialise to root
ptr = root;
// make variable to store chaacter as int representing position in alphabet
int alphaindex;
// iterate over letters in word
for (int i =0; i < LENGTH; i++)
{
// if word i == to ' character check ptr children and make new node if necesary
if ((int)&word[i] == '\'')
{
alphaindex = 26;
if (ptr-> children[alphaindex] == NULL)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return 1;
}
root->is_word = false;
for (int j = 0; j < N; j++)
{
root->children[j] = NULL;
}
// set 27th element of children to new node
ptr -> children[alphaindex] = n;
}
// set ptr to ptr[26]
ptr = ptr -> children[alphaindex];
}
else
{
// adjust alphainex
alphaindex = islower((int) word[i]) ? (int) word[i] - 97 : (int) word[i] - 65;
//check location for NULL and make new index if necessary
if (ptr -> children[alphaindex] == NULL)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return 1;
}
root->is_word = false;
for (int k = 0; k < N; k++)
{
root->children[k] = NULL;
}
// set children[alphaindex] to new node
ptr -> children[alphaindex] = n;
//set ptr to new alphaindex element of array which its self points to the new node
ptr = ptr -> children[alphaindex];
}
else
{
//set ptr to new alphaindex element of array which its self points to the new node
ptr = ptr -> children[alphaindex];
}
}
// if the character is 0 word is over, set is_word and return to while loop
if((char) word[i + 1] == 0)
{
ptr -> is_word = true;
size ++;
break;
}
}
}
printf("Size of dictionary = %i\n", size);
// Close dictionary
fclose(file);
// Indicate success
return true;
}
我相当确定,由于出现此错误的条件是我评估天气或不创建新节点的地方,因此当我稍后尝试针对它测试单词时,这将导致错误。
在此先感谢您的帮助
亚历克斯
几个紧迫的问题:
如果word包含撇号,root中的所有指针在这里都设置为NULL:
for (int j = 0; j < N; j++)
{
root->children[j] = NULL;
}
打字错误?这将使它们成为 "unfreeable"(更不用说,检查将永远找不到它们)。
else
分支中的相同问题:
for (int k = 0; k < N; k++)
{
root->children[k] = NULL;
}
撇号检查需要离散。看起来程序没有 "save" 足够的指针,但在纠正这些大的结构问题之前,您将无法完成它。
我有一些代码应该获取字典文件,读取每个单词并将其添加到 trie 数据结构中,在单词的最后一个节点上将 bool 设置为 true。
它可以运行,但是当我稍后在 check() 函数中对照字典检查单词时,它总是说错误。
Valgrind 抛出此错误;
==20700==
==20700== Conditional jump or move depends on uninitialised value(s)
==20700== at 0x40116F: load (dictionary.c:114)
==20700== by 0x400834: main (speller.c:40)
==20700== Uninitialised value was created by a heap allocation
==20700== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20700== by 0x401180: load (dictionary.c:116)
==20700== by 0x400834: main (speller.c:40)
==20700==
Killed
我环顾四周并添加了循环遍历 children[] 并在创建新节点后初始化为 NULL,但似乎仍然存在问题。
// Represents a node in a trie
typedef struct node
{
bool is_word;
struct node *children[N];
}
node;
// Represents a trie
node *root;
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Initialize trie
root = malloc(sizeof(node));
if (root == NULL)
{
return false;
}
root->is_word = false;
for (int i = 0; i < N; i++)
{
root->children[i] = NULL;
}
// Open dictionary
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
unload();
return false;
}
//declare pointer to store adress of current node
node *ptr = root;
// Buffer for a word
char word[LENGTH + 1];
for (int i = 0; i < LENGTH + 1; i++)
{
word[i] = 0;
}
int size = 0;
// Insert words into trie
while (fscanf(file, "%s", word) != EOF)
{
// make pointer to current place in trie structure and intitialise to root
ptr = root;
// make variable to store chaacter as int representing position in alphabet
int alphaindex;
// iterate over letters in word
for (int i =0; i < LENGTH; i++)
{
// if word i == to ' character check ptr children and make new node if necesary
if ((int)&word[i] == '\'')
{
alphaindex = 26;
if (ptr-> children[alphaindex] == NULL)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return 1;
}
root->is_word = false;
for (int j = 0; j < N; j++)
{
root->children[j] = NULL;
}
// set 27th element of children to new node
ptr -> children[alphaindex] = n;
}
// set ptr to ptr[26]
ptr = ptr -> children[alphaindex];
}
else
{
// adjust alphainex
alphaindex = islower((int) word[i]) ? (int) word[i] - 97 : (int) word[i] - 65;
//check location for NULL and make new index if necessary
if (ptr -> children[alphaindex] == NULL)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return 1;
}
root->is_word = false;
for (int k = 0; k < N; k++)
{
root->children[k] = NULL;
}
// set children[alphaindex] to new node
ptr -> children[alphaindex] = n;
//set ptr to new alphaindex element of array which its self points to the new node
ptr = ptr -> children[alphaindex];
}
else
{
//set ptr to new alphaindex element of array which its self points to the new node
ptr = ptr -> children[alphaindex];
}
}
// if the character is 0 word is over, set is_word and return to while loop
if((char) word[i + 1] == 0)
{
ptr -> is_word = true;
size ++;
break;
}
}
}
printf("Size of dictionary = %i\n", size);
// Close dictionary
fclose(file);
// Indicate success
return true;
}
我相当确定,由于出现此错误的条件是我评估天气或不创建新节点的地方,因此当我稍后尝试针对它测试单词时,这将导致错误。
在此先感谢您的帮助
亚历克斯
几个紧迫的问题:
如果word包含撇号,root中的所有指针在这里都设置为NULL:
for (int j = 0; j < N; j++)
{
root->children[j] = NULL;
}
打字错误?这将使它们成为 "unfreeable"(更不用说,检查将永远找不到它们)。
else
分支中的相同问题:
for (int k = 0; k < N; k++)
{
root->children[k] = NULL;
}
撇号检查需要离散。看起来程序没有 "save" 足够的指针,但在纠正这些大的结构问题之前,您将无法完成它。