配列オーバーフローを引き起こすコードを試してみましたが、gcc でコンパイルすると予期しないことが起こりました。以下はコードです:
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a[] = {0,2,4,7};
int size = sizeof(a)/sizeof(int);
int i;
printf("%d, %X\n", size, &a);
a[4] = 6;
printf("%d, %X\n", size, &a);
a[5] = 78;
printf("%d, %X\n", size, &a);
a[6] = 65;
printf("%d, %X\n", size, &a);
for (i = 0; i < size; i++) {
printf("%d, ", a[i]);
}
printf("%d, %d, %d\n", a[size], a[size+1], a[size+2]);
printf("\n");
return 0;
}
結果は次のとおりです。
4, BFC4DDF8
6, BFC4DDF8
6, BFC4DDF8
6, BFC4DDF8
0, 2, 4, 7, 6, 5, 65, 0, 0
そのため、コードではサイズの値を変更しませんでしたが、実行すると自動的に変更されました! では、なぜこれが起こるのか誰か教えてもらえますか?
PS: gcc のバージョンは 4.8.0 です。
@NPEの回答によると、のアドレスを確認するsize
と、実際にはの直後にメモリに配置されますa
。
しかし、コードを追加すると
printf("%X\n", &size);
前
printf("%d, %X\n", size, &a);
結果は
BFC39108
4, BFC3910C
4, BFC3910C
4, BFC3910C
4, BFC3910C
0, 2, 4, 7, 4, 78, 65
このとき、size
は の直前にメモリに配置されますa
。
実際、私が さんの住所をどこに印刷してもsize
、それは さんの住所のすぐ前に位置していa
ます。のアドレスを出力しないとsize
、のアドレスの直後に配置されa
ます。それでも、コンパイラの未定義の動作ですか?