1

次のように C プログラムを作成し、GCC バージョン 4.6.3 を使用してコンパイルしました。

#include <stdio.h>

int main(void)
{
    char array1[7] = "network"; // no space for \0 in array here
    char array2[5] = "network"; // even here, no space for \0 in array

    printf("1. %s\n",array1);
    printf("2. %s\n",array2);
    return 0;
}

コンパイル時:-

warning: initializer-string for array of chars is too long [enabled by default]

プログラムの出力は次のとおりです:-

1. network
2. netwo

array2 の出力:- netwo+unprintable 文字。16 進値 7F を持つ印刷不能文字。

私の質問は:-

  • array1 の値を出力しているときに、array2 を出力する場合のように、「ネットワーク」を出力した後にガベージ値を出力しないのはなぜですか。

この疑問は、配列 1 にも配列 2 にも NULL ターミネータがないという事実によって裏付けられています。なぜ、配列 2 の出力の後にのみ値がガベージになるのでしょうか?

では、GCC は配列の境界をチェックしますか?

4

3 に答える 3

4

network純粋な不運の後でゴミを出力することはありません。たまたまゼロバイトがあります。未定義の動作を呼び出しているため、どんな結果でも許可されます。

C コンパイラは長すぎるイニシャライザをチェックしますが、明示的に 'no terinating null' バージョンを許可する義務があります (ただし、警告を出すことはできますが、通常はしません; GCC 4.7.1 はしません)。

一般的な配列アクセスの場合、コンパイラは通常、配列の境界をチェックしませんが、状況によっては GCC 4.7.1 から情報を取得できる場合があります (-O最適化など、多くのオプションが必要です)。

于 2013-01-14T07:54:27.130 に答える
2

未定義の動作を悪用しています。何でも起こり得ます。

于 2013-01-14T07:53:31.780 に答える
1

長すぎる文字列で char 配列を初期化すると、未定義の動作が使用されます。これは、正しい値が表示されたとしても、何でも起こり得ることを意味します。

于 2013-01-14T07:53:52.030 に答える