描述
下面的一个问题摘自《c陷进与缺陷》,是一个很奇怪的数组越界陷入死循环问题。
在x86,vs2022、Debug环境下测试下面代码,会有什么结果?
int main()
{
int i = 0;
int arr[10] = {0};
for(i = 0;i<=12;i++){
arr[i] = 1;
printf("hehe\n");
}
return 0;
}
注:如果不限定环境,在不用的环境下测试的效果会不一样;
这个题会让你彻底感受到调试的重要性,内存的重要性,如果你是学电子的,你能更感受到这一点,一切的程序都是玩的内存,这一点非常非常重要!
题解
下面进行调试这个程序。
上面的调试可以看出,在没有溢出之前,一切正常,按照预期的运行!下面在看!
越界之后,arr[10],arr[11]里面填充了还是1,可以说是正常运行!
看上面部分,当arr[12]填充完1之后,为什么i的值也跟着变为1了,这是为什么呢?问题就出在这儿了!!!
原因就是arr[12]开辟的内存空间和i开辟的内存空间是同一块空间,当arr[12]变了,那么i的值就变了,造成死循环!!!
下面在看看内存分布:
由内存分布情况可知,i的空间和arr[12]的空间是同一块空间!!!
下面从C语言内存分配的角度来解释这一现象。
看上图,栈区内存的开辟默认是从高地址到低地址依次开辟,当然,在不同的环境下也有差别,可以自行验证,数组的开辟是从低地址到高地址依次开辟的,当数组开辟好之后,依次填充数据,当arr[9]填充完之后,发生了越界,往arr[10],arr[11]填充完之后,可能arr[12]开辟的空间和i开辟的空间是同一块空间,把arr[12]填充成1时,那么i也变成了1,造成死循环!!
完结!