每天学一点系列~诡异的死循环
Posted 白龙码~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天学一点系列~诡异的死循环相关的知识,希望对你有一定的参考价值。
Part I、题目分享
《C陷阱与缺陷》中有这样一个例题:
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;
}
请问:这个程序的输出是什么?
10个hello world?
13个hello world?
还是由于越界访问而报错?
都不是!
我们放到VS2019下运行发现——
他死循环了!?什么情况?让我们深度剖析一下这道题吧!
Part II、题目剖析
1、计算机的内存分配原则
计算机有这样的变量内存分配原则:
对于先申请内存的变量,将高地址的内存分配给它
什么意思呢?
在这道题中我们看到:我们首先创建了变量i,然后创建了数组arr,因此在程序编译运行时,计算机会将高地址的内存优先分配给i,然后再分配给数组arr
也就是:
2、数组的内存分配原则
在数组中,内存的分配原则如下:
数组元素从低地址开始,往高地址分布,且下标为0的地址最低
即:
3、调试程序
由于数组有10个元素,因此下标0~9时为正常的数组元素访问,该程序将数组内容全部改为0;
i运行到10时将arr[10]改为0
此时屏幕打印11个hello world
i运行到11时将arr[11]改为0
此时屏幕打印12个hello world
然而i等于12时,arr[12]被改为0,i也很诡异地变成了0
到这里我们就不难理解为什么这个程序会死循环了;
可这是为什么呢?
i和arr[12]都在一瞬间变成了0,是否意味着:它们两个的地址是相同的?
我们在调试中取得i和arr[12]的地址:
比较发现:二者相同
这是巧合吗?还是故意的?
根据上面我们了解到的计算机内存分配以及数组内存分配原理,我们可以由此推测i和arr的内存布局为:
结合这幅图,那么一切就都说得通了:当arr[12]改为0时,由于i和arr[12]地址相同,所以i也被改为12,因此该程序死循环!
Part III、今日小结
从这道题中我们应当意识到:随着学习的深入,从代码的表象会越来越难地看出问题的本质,想要更优质的学习,必须从根源理解代码的原理与机制!
Part IV、系列文章索引
【每天学一点系列~】字符串左/右旋的本质,你真的认清了嘛?
【每天学一点系列~】这些内存函数你知道么?还记得么[\\doge]
【每天学一点系列~】一文带你彻底弄懂结构体大小和内存对齐
创作不易,给个三连呗亲!
以上是关于每天学一点系列~诡异的死循环的主要内容,如果未能解决你的问题,请参考以下文章