2016-05-06 40 views
0

すでにソートされた2つのリンクリストtemp1temp2をマージしようとしています。私は、この例のセグメンテーションフォールト取得しています:セグメンテーションフォルト(コアダンプ) 'printf'文を実行する前にエラーが発生する

入力

temp1 : 1->NULL 

temp2 : 2->3->4->5->6->NULL 

出力

1st Output

をしかし、私はprintf文から "\ n" を削除した場合、それは直接、セグメンテーションフォールトを表示します。

2nd Output

なぜこれが起こっているのでしょうか?

コード:事前に

list *merge(list * temp1, list * temp2) 
{ 
    list *x, *y, *z; 

    x = temp1; 
    y = temp2; 
    print(x); 
    print(y); 

    z = (list *) malloc(sizeof(list)); 

    if (x->key < y->key) 
    { 
     z->key = temp1->key; 
     x = x->next; 
    } 
    else 
    { 
     z->key = temp2->key; 
     y = y->next; 
    } 
    z->next = NULL; 

    while (x || y) 
    { 
     printf("asdf\n"); 
     if (x == NULL) 
     { 
      z = append(z, y->key); 
      y = y->next; 
      printf("x\n"); 
     } 
     if (y == NULL) 
     { 
      z = append(z, x->key); 
      x = x->next; 
      printf("y\n"); 
     } 
     if (x && y) 
     { 
      printf("x && y\n"); 
      if (x->key < y->key) 
      { 
       z = append(z, x->key); 
       x = x->next; 
      } 
      else 
      { 
       z = append(z, y->key); 
       y = y->next; 
      } 
     } 
    } 
    print(z); 
    return z; 
} 

感謝。

私はすでにセグメント化エラーを削除しました。私はprintfステートメントから '\ n'を削除するとなぜ遅れるのか尋ねています。

+1

ようこそスタックオーバーフローに!デバッガを使用してコードをステップ実行する方法を学ぶ必要があるようです。良いデバッガを使用すると、プログラムを1行ずつ実行し、どこからずれているかを確認することができます。これはプログラミングをする場合に不可欠なツールです。さらに読む:[小さなプログラムをデバッグする方法](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) –

+1

なぜセグメンテーションを取得しているのか、改行を削除したときに出力が表示されないのはなぜですか? – Kevin

+1

デバッガを使ってみましたか?あなたはポインタを適切に割り当てていないか、あるいは望ましくないメモリをどこかに上書きしているかもしれません。表示されていない 'append'の中でさえもそうです。これを絞り込んで、ここの他の人があなたのコードを探して魚を見つけることを期待するのではなく、それを見つける必要があります。また、[mallocの返却をキャストしない](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – lurker

答えて

4

printfからの出力を見る前にセグメンテーションフォールトが発生する理由は、通常fflush(stdout)を実行した場合、または\nを追加してend-of-lineを取得した場合にstdoutへのprintfがフラッシュされることです。 stdoutがフラッシュされる前にセグメンテーションフォルトが発生すると、フラッシュされるのを待っているstdout内の何かが失われます。

3

ヘンリックの答えは質問のポイントまでまっすぐです。

しかし、デバッガの使用を提案しているOPにはいくつかのコメントがありました。あなたがコードをステップ実行した場合、あなたが得るものは次のとおりです。

whileループの本文の先頭に次のコードがあるとします。それによって

if(x == NULL){ 
    z = append(z,y->key); 
    y = y->next; 
    printf("x\n"); 
} 
if(y == NULL){ 
    z = append(z,x->key); 
    x = x->next; 
    printf("y\n"); 
} 

レッツ・ステップセグメンテーションフォルトが発生する直前に、x == NULL条件が真のとき

x: NULL 
y: 6-> NULL 

つまり、それゆえ我々は通って落下し、

を取得

y = y-> next 

を実行します

x: NULL 
y: NULL 

y == NULL条件は、したがって、我々はNULLポインタxを逆参照

z = append(z,x->key) 

を実行する必要があり、また事実です。ヴォイラ、それはセグメンテーションです。

このコードを修正することは困難ではありません。

+0

実際に私は '\ n'を削除したときにsegフォルトが遅れ​​ている理由を知りたいとの質問をしました。しかし、あなたの答えをありがとう – a0n1i2k3

2

Henrikは、ディスプレイとsegfaultの間の相違を非常にうまく説明しました。

本当の問題

はしかし、私はあなたのセグメンテーション違反の根本原因に興味を持っていると仮定します。すべてこれは非常にロジックであり、それはすべき事実

  • if (x==NULL)
  • if (y==NULL)
  • if (x && y)

:あなたの​​ループでは、相互に排他的であるように見える3つの異なる例を、予見しています完璧に動作します。しかし、それぞれifの本文がxまたはyに変更されていることを忘れてしまいました。

最初のリスト(つまりx==NULL)の最後に達したら、2番目のリストの次の要素に移動しますが、2番目のリストの最後に達した場合は、 LL if(y==NULL)を実行し、最初のリスト OF END過去を移動!これがセグメンテーション違反の原因です。 NULLポインタを間接参照します。

シンプルなソリューション

だけelse使用:

if (x==NULL) 
    ... 
else if (y==NULL) 
    ... 
else if (x && y) 
    ... 
関連する問題