実行時エラーの原因となったコード、つまり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である。
次回は、「マイナーな」変更について質問する前に、両方のバージョンをあらかじめ比較しておく必要があります。 – Olaf