2012-01-12 14 views
3

編集:Dijkstraの答えがこの問題を修正する方法です。私のリストはNULLに初期化されていませんでしたリンクリストのセグメンテーションフォルト

私はリストをトラバースしようとすると、segfaultsの単語の一意のリストを格納するためにリンクリストに取り組んでいます。 GDBは私を与える:

Program received signal SIGSEGV, 
    Segmentation fault. 0x0000003a07e47ff7 in vfprintf() from /lib64/libc.so.6 
    Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6_0.5.x86_64 

リストのための挿入コードは次のとおりです。

typedef struct L { char x[40] ; int occ; struct L *next ;} List; 
List *insertList(char *in, List *l) 
{ 
    List *t = calloc(1, sizeof(List)) ; 
    strcpy(t->x, in); 
    t->occ = 1; 
    t->next = l ; 
    return t ; 
} 

void printList(List *l) 
{ 
    List *l2 = l; 
    while(l2) 
    { 
     printf("%s ", l2->x); 
     l2 = l2->next; 
    } 
    return; 
} 

その一見罰金、リンクリストにそれらを挿入し、言葉をループ。リストをループして(約4200語の)単語を表示すると、約98%のishがうまく表示され、警告なしでセグメンテーションされます。

検査をもう少しすると、追加されたのと反対の順序で単語が読み込まれ(意味があります)、segfaultingする前にリストの最後から5番目の単語(5番目の単語が追加されます)に到達します。私は文字列の長さが40文字以上になるように挿入関数を調整しようとしましたが、最初に挿入される単語(およびsegfaulted)はすべて20文字未満です。

printList関数でl2-> next-> next-> next-> nextfをprintfすれば、最初に挿入された単語がそこにあります。

誰も私にこの方向性を向けることができますか?何かがどこか後半リスト内のポインタ、および長すぎる「の」文字列あなたの「次へ」を上書きしているよう

+0

リストを印刷するためのコードを入力してください。 – nmjohn

+0

まず、 'strcpy'の代わりに' strncpy'を使う習慣を覚えてください。 – thiton

+0

39文字より長い単語の1つですか? 'strncpy'を使ってメモリをオーバーランさせないようにしてください。 – ugoren

答えて

2

私の最高の推測ではなく、strcpyののそれはstrncpyはあなたの問題を解決するだろうだろう、それが聞こえる

感謝それは確かにそうするでしょう。

は、strncpyをのように文字列を正しく終了することを確認する

x[39]=0; 

を置くことを確認するために、長すぎる文字列を終了しません忘れないでください。

+0

ありがとう、私はあなたが示唆したものを試してみましたが、無駄です。ちょっと掘り起こして、何らかの理由で挿入された最初の数単語がseg faultを引き起こしていることがわかった。最初のいくつかの単語を削除すると、次のいくつかの単語(前の例で問題ない)が問題になりました – ethangk

+0

次に、コード内の別の場所にメモリが上書きされている可能性があります。 –

3

gdb(またはLinuxを使用していない場合は別のデバッガ)は、segfaultsを追跡するための私のツールです。デバッグシンボルでコードをコンパイルし、デバッガで実行します。クラッシュしたら、クラッシュの原因となっている行を調べます。必要に応じてbacktraceコマンドを使用します。これらのステップに従えば、segfaultを修正する方法がわかります。

2

最初のノードをどのように初期化していますか?

あなたは「最初の数単語がsegフォールトを引き起こしている」と言いますが、中断によって印刷が中止され、実際に問題が実際に終わりに来ています。

あなたの最初のノードにはnext = NULL;がないという仮説です(それは本当に推測です:P)。これはちょうど初期化されていないメモリです。したがって、whileループはリストの最後に到達したことを検出せず、奇妙なものを印刷しようとします。その結果、segfaultが発生します。

+0

そして勝者があります。私は数時間前にそれを稼働させることができましたが、これが問題でした。私は誤って別のリストをNULLに初期化しました。ありがとう:) – ethangk

2

これは文章です(これはSOの人には分かりません) - [] プレーン・ループの問題点は何ですか?なぜこの種のもののための有効な慣用構造があると、ループの中で反復しますか?

void printList(List *lp) 
{ 
    List *l2; 

    for(l2=lp; l2; l2 = l2->next) 
    { 
     printf("%s ", l2->x); 
    } 
    return; 
} 
+0

正直なところ、私はそれを試みることを考えていませんでしたが、はるかにきれいに見えます。最初の問題は解決されましたが、私は本当にこれが好きです。ありがとう – ethangk

関連する問題