2017-09-07 8 views
1

実行時エラーの原因となったコード、つまりseg faultについての質問を読んでいます。別の配列を使って配列を索引する - gcc 6.3ランタイムエラー

私はideone.comを使用してコードをデバッグしようとし、奇妙な結果を得ました。

私は奇妙な動作を再現するために、最小限のバージョンにコードを削除しました。したがって、このコードでは何の意味もありません。コードの目的は、奇妙な動作を示すことだけです。

コード例1:

#include <stdio.h> 

int main() { 
    int a[3] = {3, 2, 5}; 
    int s[3] = {0, 0, 0}; 
    int r = 0; 
    int i; 
    for(i = 1; i < 3; i++) { 
     while((a[i] < a[s[r]]) && (r >= 0)) 
     { 
      r--; 
     } 
     printf("initialize s[%d] to %d\n", r+1, i); 
     ++r; 
     s[r] = i; 
    } 
    printf("%d\n", r); 
    return 0; 
} 

このコードは、実行時エラーが発生します。

は、だから私は、コードには、このマイナーチェンジを行ったhttps://ideone.com/IWo6TS#stdin

を参照してください。

コード例2:

#include <stdio.h> 

int main() { 
    int a[3] = {3, 2, 5}; 
    int s[3] = {0, 0, 0}; 
    int r = 0; 
    int i; 
    for(i = 1; i < 3; i++) { 
     int t = s[r];       // These 2 lines 
     while((a[i] < a[t]) && (r >= 0))  // 
//  while((a[i] < a[s[r]]) && (r >= 0)) // instead of this line 
     { 
      r--; 
     } 
     printf("initialize s[%d] to %d\n", r+1, i); 
     ++r; 
     s[r] = i; 
    } 
    printf("%d\n", r); 
    return 0; 
} 

は今のコードは正常に動作し、出力を生成します。

initialize s[0] to 1 
initialize s[1] to 2 
1 

を使用しているコンパイラはGCC 6.3であるhttps://ideone.com/qt43DL#stdin

を参照してください。

違いがあるだけで:

.... a[s[r]] .... in example 1 

int t = s[r];  in example 2 
.... a[t] .... 

そこで問題は、なぜ最初の例は失敗しないと第二罰金実行しているのですか?

私はコード内でUBを探しましたが、何も発見できませんでした。コードにUBはありますか?

これはGCC 6.3の(既知の)バグですか?

として正しくスコット・ハンターによって指摘UPDATE 2つのコード例は、同じことをやってないです。

最初の例では、whileの体内-1可変r変化するため、それはs[-1]にアクセスwhile次の条件チェックに起因UBに失敗します。例えば、UBのように1である。

+1

次回は、「マイナーな」変更について質問する前に、両方のバージョンをあらかじめ比較しておく必要があります。 – Olaf

答えて

4

両方のバージョンでは、whileループ内でrが変更されています。したがって、aの要素のインデックスは、最初のバージョンではa[i]と比較されますが、2番目のバージョンでは変更されません。

+0

arhhh ....今私はそれを見ます:-)私はこれをあまりにも長く見てきました。私の悪い... – 4386427

+0

そして、問題は、 'r'がループ内で-1になるということです。それはそれを説明する。 – 4386427

関連する問題