一个关于调试的问题。
在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;
}
运行的结果出现了死循环:
其实在调试之前可以看出已经有栈溢出的问题,但为什么会出现死循环?
后面通过调试发现:
arr[12]和i后面会一起变化,并且值相同。
这时候我怀疑两者的地址是否是一样的,才导致这种情况:
果不其然,两者是一个地址,这才导致程序陷入了死循环。
那么这是为什么呢?
首先我们要知道,i和arr都是局部数据,局部数据放在栈区。
而我们写的这个代码变量i在前,存放在高地址,
栈区内存的使用习惯是:
先使用高地址的空间,再使用低地址的空间。
并且数组随着下标的增长,地址是由低到高变化的。
所以,当代码可以适当的往外越界,有可能就可以覆盖到i,这里arr[12]就刚好访问到了i,这样一来,i在自增的时候,arr[12]也跟着改变,从而i永远不可能大于12跳出循环,所以陷入了死循环。
至此,我们在写代码的使用一定要注意不能越界,并且要仔细调试检查。
这个问题出自《C陷阱与缺陷》