1

私はCの初心者ですが、今日、何時間も困惑する問題に遭遇し、問題が発生した条項を差し引きました。

でコンパイルしましたArchlinux(gcc)

#include <stdio.h>

#define SIZE 10

int main()
{
    char s[SIZE]; 
    int i;
    for (i = 0; i < SIZE; )
        s[i++] = 'm';
    s[i++] = '\n';
    s[i] = '\0';
    printf("%s/D\n", s, i);

    return 0;
}

エラーなしで動作しました。

出力はmmmmmmmmmm11です。

1行を削除します。s[i++] = '\n';

#include <stdio.h>

#define SIZE 10

int main()
{
    char s[SIZE]; 
    int i;
    for (i = 0; i < SIZE; )
        s[i++] = 'm';
    s[i] = '\0';
    printf("%s %d\n", s, i);

    return 0;
}

「i」は0になりました。出力:mmmmmmmmmm 0

しかし、一度Cent OS(gcc)でコンパイルされました。

「i」は0になりませんでした。

に戻るArchlinux。別の行に入りました。int a = i", to reference i;

#include <stdio.h>

#define SIZE 10

int main()
{
    char s[SIZE]; 
    int i;
    for (i = 0; i < SIZE; )
        s[i++] = 'm';
    s[i] = '\0';
    int a = i;
    printf("%s/D\n", s, i);

    return 0;
}

そして今回は「i」は0になりませんでした。

私は初心者です、誰かが何が起こっていたのか教えてください。

これが私が犯した愚かな間違いである場合は、私に知らせてください。投稿を削除します。

ありがとう!

4

2 に答える 2

2

C配列はゼロベースであるため、この例の有効なインデックスは[0..SIZE-1]です。ループの最後に、i==SIZEs[SIZE]次に、配列の終わりを超えた1つの要素に書き込みます。これは未定義の結果をもたらします。

テストでは、どちらの場合も&s[SIZE] == &i書き込みます。i最初のケースでは、のASCII値は'\n'たまたま期待したものであるiため、バグに気付くことはありません。2番目のケースでは、運が良ければ、0にリセットiして、配列のオーバーフローを見つけます。

修正は、char配列にヌルターミネータ用のスペースを残して、ループを1回早く終了することです。

for (i = 0; i < SIZE-1; )
//                  ^^
于 2013-01-09T09:47:40.400 に答える
0

ここで、配列のサイズは10と定義されていますが、forループの最後で、11番目の位置に割り当てようとしているため、この未定義の動作が表示されます。

#include <stdio.h>

#define SIZE 10

int main()
{
    char s[SIZE]; 
    int i;
    for (i = 0; i < SIZE; )
        s[i++] = 'm';
    s[i] = '\0'; // here after end of your loop you are assigning a[10]='\0' that is makin it as undefined behaviour.
    int a = i;
    printf("%s/D\n", s, i);

    return 0;
}
于 2013-01-09T09:54:05.050 に答える