2017-11-02 14 views
1

2d配列の項目からリンクリストを作成するプロジェクトで作業しています。配列は正しく設定されていますが、リンクリストを作成する方法でセグメンテーション違反が発生しています。どこで障害が発生しているのかをデバッグしようとすると、私はprint文をメソッド呼び出しの1行上に置いていますが、print文は決して印刷されません。しかし、私がメソッド呼び出しをコメントアウトした場合、printステートメントは印刷されました。セグメンテーションフォルトにより、以前の関数が発生しません。

main() 
{ 
     struct String *list; 
     char words1[100][1000]; 
     for(int i = 0; i < 100; i++) 
       words1[i][0] = '\0'; 

     char *words2[100]; 

     for(int i = 0; i < 100; i++) 
       words2[i] = words1[i]; 

     char ** words = words2; 

     getStrings(words); 

     for(int i = 0; i < 100; i++) 
     { 
       if(words[i][0] == '\0') break; 
       printf("%s\n", words[i]); 
     } 

     printf("Creating list\n"); //**(RIGHT HERE)** <----------- 
     //createList(list, words); 
     //sortStrings(list); 
     showStrings(list); 
     return 0; 
} 

struct String 
{ 
     char *s; 
     struct String *next; 
}; 

void createList(struct String * list, char **words) 
{ 
     list = NULL; 
     struct String *node; 

     int counter = 0; 
     while (1) 
     { 
       if (words[counter][0] == '\0') break; 

       printf("Adding: %s", words[counter]); 

       node = (struct String *) malloc(sizeof(struct String)); 
       node->s = words[counter]; 
       node->next = NULL; 
       list->next = node; 
       list = node; 
       counter++; 
     } 
} 

void getStrings(char **s) 
{ 
    int count = 0; 
    for(int i = 0; i < 1000; i++) 
    { 
     int ret = scanf("%[^;]", s[i]); 
     if(ret < 0) break; 
     count++; 
     getchar(); 
    } 
} 

なぜcreateList()メソッドでセグメンテーションフォールトが、それが実行されない(または少なくとも表示されていない)する前に呼び出されている必要があります機能を引き起こすのでしょうか?

編集:コードにgetStrings()メソッドを追加しました。

+1

あなたがいるので:あなたはまた、ファイルオブジェクトのバッファリングを操作するためsetvbuf機能を使用することができますhttp://en.cppreference.com/w/cpp/io/c/fflush

おそらくスタックや他のメモリをゴミ箱に入れてしまいます。 segfaultの後にプログラムが正しく動作することを期待するべきではありません。 – OldProgrammer

+1

1) 'list-> next = node;': 'list'は初めてNULLになります。 2) 'list'は' main'で初期化されていません。 ( 'createList'は' main'の 'list'を更新しません) – BLUEPIXY

+0

文字列はリストノード構造体にとって非常に悪い選択です。 – jwdonahue

答えて

4

printf機能が遅すぎる可能性があるため、関数はすぐに標準出力にデータを書き込みません。代わりに、stdoutオブジェクトの内部バッファにデータを収集することがあります。バッファーがいっぱいになると(あるいは改行に達すると)、その内容は "フラッシュされ"ます(下にあるファイルに書き込まれます)。通常の実行中、このデータはプログラムが終了する前にも書き込まれますが、プログラムがあらかじめ終了しているため、そのバッファを空にしてデータを失うことはできません。

printfの後ろにfflush(stdout);ステートメントを追加して、強制的にデータを書き込むことができます。

通常、ターミナルバッファへの書き込みがフラッシュされるのは、\nです。代わりにパイプに書き込んでいると思います(あなたのIDEがあなたのプログラム出力をリダイレクトするかもしれません)。ファイルはここストリーム当接

あなたはより多くを読むことができます:http://en.cppreference.com/w/cpp/io/c

そして、ここについてfflushを:http://en.cppreference.com/w/cpp/io/c/setvbuf

0
main() 
    { 
    /* uninitialized list head must be initialized as NULL */ 
    struct String *list = NULL; 
    . . .  

    void createList(struct String * list, char **words) 
    { 
    /* Value of list changing only in local scope, list must be a  
     `struct String **` type. */ 
    list = NULL; 
    . . . 
      /* access to field on NULL pointer -> segmentation fault */ 
      list->next = node; 
関連する問題