3

逆文字列関数を作成したいのですが、次のように実行しました。

void reverse_str(char s[])  {
    int i, j;
    char ch;
    for(i = 0, j = strlen(s) - 1; i < j; i++, j--)  {
        ch = s[i];
        s[i] = s[j];
        s[j] = ch;
    }
    return ;
}

しかし、何らかの理由でに変更i < jするi != jと、セグメンテーション違反が発生します。これは、ijがポインタである場合にも発生します。なんで?

4

4 に答える 4

6

これはほぼ確実に、ijが互いに受け渡しを行うためです (ここでは、それらがインデックスであるかポインターであるかは関係ありません)。たとえば、文字数が偶数の文字列では、この問題が発生します。

string の次のシーケンスを検討してくださいdrum

     0123 <- indexes
     ----
s = "drum", i = 0, j =  3, swap d and m.
s = "mrud", i = 1, j =  2, swap r and u.
s = "murd", i = 2, j =  1, swap u and r, oops, we've passed each other.
s = "mrud", i = 3, j =  0, swap m and d.
s = "drum", i = 4, j = -1, swap who knows what, undefined behaviour.

奇数の長さの文字列の場合、最終的に(中央の文字で)i等しいため、この問題は発生しないことに注意してください。j

このチェックでは、ポインターの等価性相互に渡すi < jポインターの両方が検出されるため、この問題も修正されます。

于 2012-06-21T10:25:57.010 に答える
3

j が奇数で始まる場合 (s文字数が偶数の場合)、 i と j が等しくなることはありません。したがって、ループは array の境界の外で続行されますs

たとえば、 if i = 0andj = 1が最初に評価されたとき、次のループにはand がi = 1ありj = 0(まだ等しくないことに注意してください)、3 番目のループにはi = 2andj = -1があるため、エラーが発生します。

于 2012-06-21T10:25:29.710 に答える
1

どのように関数を呼び出していますか? つまり、渡す文字配列が書き込み可能であると確信していますか?

メモリに問題がなければ、使用するとクラッシュする可能性があります。これは、予期したときにクラッシュする!=という保証がないためです。

于 2012-06-21T10:26:10.020 に答える
1

strlen(s) - 1が奇数の場合、条件はi!=j常に真になります。

于 2012-06-21T10:26:56.670 に答える