私は、スペルミスの単語を保存して確認するためにトライを使用するスペルチェッカーを作成しました。テキストファイル辞書をメモリにロードし、単語を受け入れてスペルミスをチェックし、メモリをアンロードします。プログラムは正常にコンパイルされますが、実行するとセグメンテーションフォルトが生成されます。 valgrindに基づいて、問題は私の挿入関数で初期化されていない値を使用しているようです。スペルチェッカーでサイズ8の初期化されていない値を使用
//If word not present, inserts word into trie
//If the word is a prefix of a node, marks the "leaf node" (end-of-word node)
void insert(struct node *root, const char *word)
{
int length = strlen(word);
int index = 0;
//start from root node
struct node *tempNode = root;
for(int i = 0; i < length; i++)
{
//if the current letter in word is a letter
if(word[i] != '\'')
//convert the alphabet to it's respective index number
index = CHAR_TO_INDEX(tolower(word[i]));
else
//assign index number 27 (for apostrophe)
index = INPUT_SIZE;
//create a new node if path doesn't exist (is NULL)
if(!(tempNode->children[index]))
tempNode->children[index] = getNode();
//go to next node
tempNode = tempNode->children[index];
}
//mark last node as leaf
tempNode->isWord = true;
}
インサート(トライにおける場所ワード)(メモリに辞書txtファイルから単語を移動させる)負荷によって呼び出される:NULLに初期化され、新しいノードを作成
bool load(const char *dictionary)
{
//initialise variables
char ch;
char word[LENGTH] = "";
int counter = 0;
struct node *root = getNode();
//open file to start inserting words
FILE *file = fopen(dictionary, "r");
//load words in dictionary into memory
while (EOF)
{
while((ch = fgetc(file)) != '\n')
{
word[counter] = ch;
counter++;
}
//whole word found, insert word and reset counter, increment word count
insert(root, word);
counter = 0;
word_Count++;
}
//close all open files if EOF is reached, else loading has failed- return false
if(EOF == true)
{
fileLoaded = true;
fclose(file);
return true;
}
else return false;
}
とgetNode():
//Returns new trie node initialised to NULL
struct node *getNode(void)
{
//initialise new node
struct node *newNode = NULL;
newNode = malloc(sizeof(struct node));
//proceed if enough memory to allocate
if(newNode)
{
//initialise pointers
for(int i = 0; i < INPUT_SIZE; i++)
newNode->children[i] = NULL;
newNode->isWord = false;
}
else return false;
return newNode;
}
構造体ノードの定義:
//Returns new trie node initialised to NULL
struct node *getNode(void)
{
//initialise new node
struct node *newNode = NULL;
newNode = malloc(sizeof(struct node));
//proceed if enough memory to allocate
if(newNode)
{
//initialise pointers
for(int i = 0; i < INPUT_SIZE; i++)
newNode->children[i] = NULL;
newNode->isWord = false;
}
else return false;
return newNode;
}
valgrindのに従って
エラー:
Conditional jump or move depends on uninitialised value(s)
==9334== at 0x4011DD: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334== Uninitialised value was created by a heap allocation
==9334== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9334== by 0x4010CB: getNode (dictionary.c:40)
==9334== by 0x4011E7: insert (dictionary.c:85)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334==
==9334== Use of uninitialised value of size 8
==9334== at 0x4011D5: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334== Uninitialised value was created by a heap allocation
==9334== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9334== by 0x4010CB: getNode (dictionary.c:40)
==9334== by 0x4011E7: insert (dictionary.c:85)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334==
==9334== Invalid read of size 8
==9334== at 0x4011D5: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334== Address 0x91 is not stack'd, malloc'd or (recently) free'd
==9334==
==9334==
==9334== Process terminating with default action of signal 11 (SIGSEGV)
==9334== Access not within mapped region at address 0x91
==9334== at 0x4011D5: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
valgrindのがフル--leakチェック=フル、--leakチェック=で実行し、--show-漏れ種類=全てました。私は前の投稿と同様のエラーを参照しようとしましたが、文脈の違いは私が何をすべきかを特定するのを困難にしています。 84行目はif(!(tempNode-> children [index]))を読み込む行です。これは(私にとって)問題の根本的な原因と思われます。
ありがとうございました!
デバッガがあなたにもっと教えてくれるかもしれない –
structノードとは何ですか?子供はポインタの配列ですか? – Elan
ここで[MCVE]が役に立ちます。 –