以下代码在VS中运行居然出现了死循环,那这是什么原因呢?
#include<stdio.h>
int main()
{
int i = 0;
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0;
}
首先我们要知道,局部变量和函数形参是存放在栈区的,所以数组是存放在栈区,且栈区的使用习惯和数组占内存的规律如下:
栈区的使用习惯:先使用高地址处的空间,再使用低地址处的空间。
数组占内存的规律:数组随着下标的增长,地址是由低到高变化。
根据上述代码,存放如下:
i是最先存放的,且存放的位置在最高处(相对于数组其它元素所在的地址)的地址。
出现死循环的原因:当i与所谓的arr[12],也就是在arr[9]后八个字节的变量占同一块存储空间,换句话说,就是i恰好和分配到arr[9]后八个字节的位置,i就是arr[12]。当i=12时,执行完arr[12]=0的语句后,i=0,循环从0开始,当i再次=12,再次执行完arr[12]=0的语句后,i又从0开始,如此循环往复,就造成了死循环。
接下来我将调试代码,更清楚展示这个过程
i==10
i==11
(我们这时就已经可以发现,随着i的变化,arr[12]也在变化)
i==12
这时我们即可证明,i就是arr[12]。
但是这个代码非常依赖环境,如果我们不用Debug版本而是用Release版本,此时代码会被优化,i的位置就不会与arr[12]的位置相同,因此也不会出现死循环。并且,如果更换编译器,i的位置会变换,可能不会与arr[12]中的位置重合,因此就不会出现死循环。
如果将代码中i的上限改成11或者10,就只会弹出栈损坏的警告,不会出现死循环。
所以,当我们遇到一个关于数组越界会出现什么问题或者运行结果是什么的问题,假设问题代码就是我所列举的代码。
我们可以回答:
1、可能出现栈破坏的警告,因为数组越界访问了,最终打印出11个或者12个hehe
2、可能会出现死循环的情况,因为i的位置可能与arr[12]相同,当i==12时,执行完arr[12]=0后,i随之也变成0,再重新循环,如此循环往复,造成了死循环,会打印出很多个hehe,直至消耗完内存,停止打印。
如果喜欢我的文章就点个赞再走吧!谢谢!