2017-06-19 11 views
0

私は、スペルミスの単語を保存して確認するためにトライを使用するスペルチェッカーを作成しました。テキストファイル辞書をメモリにロードし、単語を受け入れてスペルミスをチェックし、メモリをアンロードします。プログラムは正常にコンパイルされますが、実行するとセグメンテーションフォルトが生成されます。 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]))を読み込む行です。これは(私にとって)問題の根本的な原因と思われます。

ありがとうございました!

+0

デバッガがあなたにもっと教えてくれるかもしれない –

+1

structノードとは何ですか?子供はポインタの配列ですか? – Elan

+0

ここで[MCVE]が役に立ちます。 –

答えて

0
while((ch = fgetc(file)) != '\n') 
{ 
    word[counter] = ch; 
    counter++; 
} 
//whole word found, insert word and reset counter, increment word count 
insert(root, word); 

これは、未定義の動作を引き起こすコードの一部です。

あなたの文字列wordはヌルで終端されていませんが、insertはそれを期待しています(最初はヌルで終了する文字列を期待するstrlenです)。

簡単な修正は、すべてのものが境界内にあると仮定しinsertにコールする前に

word[counter] = '\0'; 

だろう。

関連する問題