# 判断下面代码运行后出现的情况 (在VS X86 Debug环境中)
int main()
{
int i = 0;
int arr[10]={0};
for(i=0;i<=12;i++) //注意这里的越界赋值!
{
arr[i] = 1;
printf("haha\n");
}
return 0;
}
- 运行结果是 死循环打印 haha
下面是调式过程:
1.数组有效空间下标是从0~9共十个,而arr[10]、arr[11]、arr[12]是越界空间。
2.循环给数组元素赋值时,到arr[10]属于非法访问,正常情况下程序是会报错,这里出现的死循环带有偶然性,也不算偶然(特定环境下),这个说法下面会详细介绍。
下面是调试界面,当 i = 12时,循环进行判断,满足 i<=12条件, 继续给 arr[12] 赋值 <arr[12] = 1>。注意未赋值前界面中 arr[12] 的值与 i 的值相同。
判断 i 满足循环条件后进行赋值 arr[12] = 1,此时变量 i 值也变成了数值1! 正常情况是 i 应该为 13。而这里的i 值变为1,说明给arr[12]赋值的时候间接也给变量 i 修改了值。
给arr[12]赋值的同时修改了i的值,唯一的可能就是 arr[12]与i是同一个地址空间的不同名称。
在VS X86 Debug环境下,经调试发现确实如此,arr[12] 与 i 是同一块地址空间,对其中任一一个修改值,另一个的值也随之变更。
1.栈区内存的使用规则是:由高到低(地址空间编码大小),变量i 的地址值 大于数组 arr的整体地址值。
2.数组在内存中的存放规则:随下标的递增,地址值由低到高。
结论:为什么 i 和 arr数组之间刚好空出2个整形空间,没错,就是巧合!在不同的编译器下可能空出的空间大小是不一样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以不同的编译器之间就有差异。