2017-09-05 10 views
0

ロード機能のセグメンテーションが継続しています。ロード機能トライセグメンテーションフォールト

bool load(const char *dictionary) 
{ 
    //create a trie data type 
    typedef struct node 
    { 
     bool is_word; 
     struct node *children[27]; //this is a pointer too! 
    }node; 

    //create a pointer to the root of the trie and never move this (use traversal *) 
    node *root = malloc(sizeof(node)); 
    for(int i=0; i<27; i++) 
    { 
     //NULL point all indexes of root -> children 
     root -> children[i] = NULL; 
    } 


    FILE *dptr = fopen(dictionary, "r"); 
    if(dptr == NULL) 
    { 
     printf("Could not open dictionary\n"); 
     return false; 
    } 



    char *c = NULL; 


    //scan the file char by char until end and store it in c 
    while(fscanf(dptr,"%s",c) != EOF) 
    { 
     //in the beginning of every word, make a traversal pointer copy of root so we can always refer back to root 
     node *trav = root; 

     //repeat for every word 
     while ((*c) != '\0') 
     { 
     //convert char into array index 
     int alpha = (tolower(*c) - 97); 

     //if array element is pointing to NULL, i.e. it hasn't been open yet, 
     if(trav -> children[alpha] == NULL) 
      { 
      //then create a new node and point it with the previous pointer. 
      node *next_node = malloc(sizeof(node)); 
      trav -> children[alpha] = next_node; 

      //quit if malloc returns null 
      if(next_node == NULL) 
       { 
        printf("Could not open dictionary"); 
        return false; 
       } 

      } 

     else if (trav -> children[alpha] != NULL) 
      { 
      //if an already existing path, just go to it 
      trav = trav -> children[alpha]; 
      } 
     } 
     //a word is loaded. 
     trav -> is_word = true; 
    } 
    //success 
    free(root); 
    return true; 
} 

初期化中にNULLに新しいポインタが正しく指されているかどうかを確認しました。私は3つのタイプのノードを持っています:ルート、トラバーサル(移動のため)、そしてnext_node。 (i)それらをmallocする前に、ノードをヌルにすることを許可しましたか? (ii。)また、ノードが初期化され、if文内でmallocされている場合、 'next_node'を解放するにはどうすればよいですか? node *next_node = malloc(sizeof(node));(iii。)ノードをグローバル変数として設定する場合は、どのノードをグローバル変数にする必要がありますか? (iv。)最後に、グローバル変数をどこで設定するのですか?speller.cのメインの内側、メインの外側、または他の場所?それはたくさんの質問ですので、あなたはそれらのすべてに答える必要はありませんが、答えられたものに答えることができればいいでしょう!私のコード内の他の特質を指摘してください。たくさんあるはずです。私はほとんどの答えを受け入れます。

+0

ような何かを試すことができますが、あなたはどのであなたのコードのセグメンテーションフォルトを並べる把握します。また、コード内でエラー処理と検証を行う必要があります。例えばこれらの行は 'int alpha =(tolower(* c) - 97); if(trav - > children alpha == NULL) 'はあなたができることではないので、あなたの入力が有効かどうかを知る必要があるので、' alpha = '' 0 = 'と' <27あなたが 'trav - > children [alpha]' – nos

+1

'char * c = NULL;'のインデックスとして使うことができるようになる前に '' c ''にメモリを割り当てたことがないので、fscanfは書き込み中に失敗します。 – Matt

+0

'fscanf'は、着信データを格納する場所へのポインタを要求します。 'c'を' NULL'にセットして 'fscanf'に渡すので、あなたが行を読むとき、それはヌルポインタを介して書き込もうとします。たとえば、256文字のラインバッファを作成し、それを 'fscanf'の引数として渡します。 –

答えて

0

セグメンテーションフォルトの原因は、メモリを割り当てていないポインタ "c"です。あなたのプログラムでも

、 - あなたはポインタCにメモリを割り当てたら

//scan the file char by char until end and store it in c 
while(fscanf(dptr,"%s",c) != EOF) 

、cがファイル辞書から読み出しワードを保持します。あなたのコードで以下 、あなたは「\ 0」をチェックされている

while ((*c) != '\0') 
    { 

をcharacter-しかし、このコードは、無限の実行なってしまいますので、そのあなたは、文字列の読み込みに次の文字を指すように、Cのポインタを移動されていませんwhileループ。 あなたはあなたのコードをデバッグする必要がthis-

char *tmp; 
tmp = c; 
while ((*tmp) != '\0') 
{ 
    ...... 
    ...... 
    //Below in the loop at appropriate place 
    tmp++; 
} 
関連する問題