Cは、実行時に配列の境界チェックをしない。 そこで、配列の境界を越えて値を書き込める。
#include <stdio.h>
int main() {
int x[2];
int y;
x[0] = 25;
y = 72;
printf ("x[0] -> %d\n",x[0]);
printf ("y -> %d\n",y);
x[-1] = 122; /*** 境界を越えた書込 ***/
printf ("x[0] -> %d\n",x[0]);
printf ("y -> %d\n",y);
}
実行結果は次の通り。x[-1]は変数yのことであり、yの値が書き換わってしまっ た。
x[0] -> 25 y -> 72 x[0] -> 25 y -> 122
↑小さい番地 -------------------- | y | -------------------- | x[0] | -------------------- | x[1] | -------------------- | ... | -------------------- | ... | -------------------- ↓大きい番地
配列の部分をポインタを使って書けば次の通り。
#include <stdio.h>
int main () {
int x,y;
int *px,*py;
x = 25;
y = 72;
px = &x;
py = &y;
printf ("x(%p) -> %d\n",px,x);
printf ("y(%p) -> %d\n",py,y);
*(px - 1) = 122;
printf ("x(%p) -> %d\n",px,x);
printf ("y(%p) -> %d\n",py,y);
}
x(0xbffff8d8) -> 25 y(0xbffff8d4) -> 72 x(0xbffff8d8) -> 25 y(0xbffff8d4) -> 122
↑小さい番地
--------------------
0xbffff0d4 | y (4byte) |
--------------------
0xbffff0d8 | x (4byte) |
--------------------
0xbffff0dc | ... |
--------------------
0xbffff0e0 | ... |
--------------------
↓大きい番地