目录
一.例题
二.解题思路
三.底层逻辑?
一.例题
求下面代码的运行结果
#include <stdio.h>
int main()
{
int i = 0;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hello world\n");
}
return 0;
}
二.解题思路
看到题目,我相信大部分人的答案都是循环12次打印 hello world? 。那么我们放到VS编译器下运行看看答案是不是和我们所想一样。
?。?如图所示,我们并没有得到12个hello world 。程序视乎是陷入了死循环,一直在打印hello world 。那么究竟是什么原因导致程序陷入死循环呢,我们可以一步一步调试来寻找错误
当代码运行到这一步时,我们可以清晰的看到数组arr和i都成功创建并初始化。
??当i=9时,我们发现数组已经全部被改为0了,如果我们继续让代码运行下去的话,毫无疑问,数组必然越界访问。
?当我们继续运行代码后,我们在监视窗口可以看到即使越界访问arr[10]arr[11]依然被我们改成0了,这是因为当数组越界访问时,arr[10]表示数组最后一个元素的后一个地址,我们继续让代码运行下去。
我们可以很轻易的发现,当i=12时,继续运行代码时,i和arr[12]一起被修改成了0,显然,问题就是出在了这里。那么究竟是什么原因导致i和arr[12]一起被修改呢??
?
我们在监视里通过&i,&arr[12]获取到了i和arr[12]的地址,发现他们的地址竟然是一样的,那就说明在这串代码中,当数组arr越界访问后获取到了i的地址,因此当arr[12]修改为0时,i也同时被修改为0。因此程序陷入了死循环之中。
三.底层逻辑?
内存主要分为三大块区域,分别是栈区、堆区、静态区。
栈区主要存放局部变量,堆区主要用于动态内存的分配(比如malloc申请的区域)?,静态区主要用来存储静态数据、全局数据、常量。?
在本题中我们要知道:
1.局部变量是存放在栈区的,因此i和arr数组都是在栈区开辟内存。
2.我们要了解栈这种数据结构,栈的特点是先进后出、后进先出,它的使用顺序是先使用高地址再使用低地址。
3.数组的开辟是由低地址向高地址逐步递增的。
?
?经过测试,在不同编译器下,i和arr之间的空白内存区域是不一样的,在VS编译器下,i开辟后是隔两个整形空间再开辟arr的内存空间,而在VC6.0中,i和arr数组之间仅有一个空白的内存空间。
希望这道例题能够对你有所帮助,感谢你的观看!?
|