大家请看这样一段代码(工具:VC++6.0):
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
int arr[10];/* 这里注意循环变量i与数组arr的定义顺序 */
for(i = 0; i <= 10; i++)/* 这里越界了 */
{
arr[i] = 0;
printf("arr[%d] = %d\n", i, arr[i]);
getch();/* 等待一次输入,按一下键盘,循环一次,编译调试 */
}
printf("Program is end!\n");
return 0;
}
很显然,在本段代码中,出现了一个越界操作的问题。不过幸运的是,编译还是通得过的。大家猜想结果是什么呢?我原本以为会输出如下字符:
arr[0] = 0
arr[1] = 0
arr[2] = 0
arr[3] = 0
arr[4] = 0
arr[5] = 0
arr[6] = 0
arr[7] = 0
arr[8] = 0
arr[9] = 0
arr[10] = 0
Program is end!
不过,结果却是这样:
什么意思呢?就是说"Program is end!"根本没打印出来,换句话说就是:程序进入了一个死循环。
要是我换一种写法:
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[10];
int i;/* 这里注意循环变量i与数组arr的定义顺序 */
for(i = 0; i <= 10; i++)/* 这里越界了 */
{
arr[i] = 0;
printf("arr[%d] = %d\n", i, arr[i]);
getch();/* 等待一次输入,按一下键盘,循环一次,编译调试 */
}
printf("Program is end!\n");
return 0;
}
结果又是怎样呢?
这次成功的打印出"Program is end!"了。不过,系统却弹出了这样一个提示窗口——arr.exe已停止工作。这是由于我们越界操作,导致程序崩溃了。这个好理解,纳闷的是,同样的代码,为什么结果却出现这么大的不同呢?
两端代码唯一的不同就在于循环变量i和数组arr的定义先后顺序不一样,问题,也只可能出现在这里。
原来,在VC++6.0编译器中,按照内存地址递减的方式来给变量分配内存。在前一段代码中,地址分配如下:
在越界访问arr[10]的时候,实际上进行的操作时为变量i所在位置赋值为0,故,每次执行到i = 10的时候,i就被赋值为0,程序永远出不来。成为了一个死循环。
而在后一段代码中,内存分配情况如下:
当执行到arr[10] = 0的时候,实际上是把上图arr[9]左边的一块区域设置为0,与i无关,故程序能跳出循环。但这种访问时非法的,故,程序会异常终止。
原文链接:https://blog.csdn.net/u013000434/article/details/17403311