2017-08-19 4 views
0

私は、テキストファイルをスペルチェックするためのトライデータ構造を実装しようとしています。現在、ファイル内のカップルワードで動作するように見えますが、segフォルトになります。私は犯人を見つけるためにデバッグを試みましたが、私が見つけたのは、 "文字"の値が一見ランダムな負の値を保持しているということでした(それは1と27の間でなければなりません)。通常、segフォルトの問題はプログラムを開始した直後に表示されるので、なぜプログラムの途中で問題が発生しているのかわかりません。CのTrie実装でのセグメンテーションフォルト

/** 
    * Implements a dictionary's functionality. 
    */ 

    #include <stdbool.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <ctype.h> 

    #include "dictionary.h" 


    //create global root node 
    Trienode *root; 
    //create word counter for size() function 
    unsigned int wordcount = 0; 

    //creates an empty node 
    Trienode * newnode() 
    { 
     Trienode *nnode = NULL; 
     nnode = (Trienode *)malloc(sizeof(Trienode)); 
     //initialize new node with null pointers and values 
     nnode -> parent = NULL; 
     for(int i = 0; i < 27; i++) 
     { 
      nnode -> children[i] = NULL; 
     } 
     return nnode; 
    } 

    void cleartrie(Trienode *head) 
    { 
     //if child node exists, free it, else continue with next iteration in for loop 
     if(head) 
     { 
      for(int i = 0; i < 27; i++) 
      { 
       cleartrie(head -> children[i]); 
      } 
      free(head); 
      head = NULL; 
     } 
    } 

    /** 
    * Returns true if word is in dictionary else false. 
    */ 
    bool check(const char *word) 
    { 
     int i = 0; 
     int letter; 
     Trienode *head = root; 

     while(word[i] != '\0') 
     { 
      if(isalpha(word[i])) 
      { 
       letter = word[i] - 'a'; 
      } 
      else //it must be an apostrophe 
      { 
       letter = word[i] - 13; 
      } 
      if(!(head -> children[letter])) 
      { 
       return false; 
      } 
      else //a pointer must exist 
      { 
       head = head -> children[letter]; 
      } 
      i++; 
     } 
     return true; 
    } 

    /** 
    * Loads dictionary into memory. Returns true if successful else false. 
    */ 
    bool load(const char *dictionary) 
    { 
     //open file 
     FILE *infile = fopen(dictionary, "r"); 
     Trienode *parnode; //parent node 
     root = newnode(); 
     Trienode *curnode = root; //current node 

     int letter = 0; 
     //while not end of file, read words 
     while(fgetc(infile) != EOF) 
     { 
      //while not end of word, read letters 
      for(;;) 
      { 
       int c; 
       //read current letter in file 
       c = fgetc(infile); 
       //convert input char to corresponding array location (a - z = 0-25, apostrophe = 26) 
       if(isalpha(c)) 
       { 
        letter = c - 'a'; 
       } 
       else if (c == '\'') 
       { 
        letter = c - 13; 
       } 
       //if end of string, exit loop 
       else if (c == '\0') 
       { 
        //end of word, so endofstring = true 
        wordcount++; 
        break; 
       } 
       //move to next letter if not either apostrophe or alphabetical 
       else 
       { 
        break; 
       } 
       //if pointer to letter of word doesn't exist, create new node 
       if(curnode -> children[letter] == NULL) 
       { 
        curnode -> children[letter] = newnode(); 
       } 
       //child node is the new current node 
       parnode = curnode; 
       curnode = curnode -> children[letter]; 
       curnode -> parent = parnode; 

      } 
      //return to root node 
      curnode = root; 
     } 

     fclose(infile); 
     return true; 
    } 


    /** 
    * Returns number of words in dictionary if loaded else 0 if not yet loaded. 
    */ 
    unsigned int size(void) 
    { 
     return wordcount; 
    } 

    /** 
    * Unloads dictionary from memory. Returns true if successful else false. 
    */ 
    bool unload(void) 
    { 
     cleartrie(root); 
     if (root == NULL) 
     { 
      return true; 
     } 
     return false; 
    } 

テキストの壁には申し訳ありませんが、大部分は文脈のためだけです(私は願っています)。 segフォールトエラーは、チェックヘルパー関数のif(!(head - > children [letter]))行で発生しています。

ありがとうございます!

+0

あなたのコードにTrienodeが何であるかわかりません。それは構造体ですか? – Jerinaw

+1

デバッガを使用しましたか?あなたのコードのどの部分にセット・フォルトが正確に発生しますか(デバッガはあなたに指示する必要があります)? 'letter 'の価値がどこまで狂っているのが分かりますか?これは部分的なコードリストなので(問題を絞り込むことなくすべてのコードを記述することはお勧めしません)、問題がどこを見ているのかを言うのは難しいです。より多くのデバッグを行い、それを絞り込んでください。 – lurker

+0

valgrindを使用します。あなたの問題がどこにあるか教えてくれます。 –

答えて

1

テストファイルに大文字が含まれている可能性があります。この場合、'a'を引いて文字を再マッピングしようとすると、'A' < 'a'以降、負の数になります。 ASCII Tableをご覧ください。文字を最初に小文字に変換すると、問題が解決するはずです。

関連する問題