通过调试发现程序死循环的原因

提示:本文章基于VS2022x86环境。

通过调试发现程序死循环的原因


提示:以下是本篇文章正文内容,下面案例可供参考

一、死循环代码展示

#define _CRT_SECURE_NO_WARNINGS 1
#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;
}

这个代码并不会报错,而是会无限死循环打印hehe。

二、调试分析

在这里插入图片描述
在这里插入图片描述
当i=9时,hehe已经打印了九次,马上要将容量为四十个字节的整型数组的最后一个元素赋值为零,第十次hehe也快要打印。如果此时的循环条件是 i<10,那么循环即将结束。但是这里的循环条件为 i<=12,当第十次循环进行完后,对于一个只能储存十个元素的数组来说,程序还能进行下去吗?


程序继续进行调试下去。

在这里插入图片描述
在这里插入图片描述
此时发现程序依然在进行,数组虽然越界了,但是在数组后面,依然开辟了一块区域用于存储arr[10]。hehe也跟着打印了11次。同时发现在后续的调试下,发现arr[11]也成功进行了存储。如下所示:
在这里插入图片描述


那么按照这种情况,当循环条件i大于12时,循环就停止了,最多打印13次hehe。为什么循环没有出来,一直进行下去了呢?
接着往下调试,监视arr[12]。

在这里插入图片描述
此时发现,进入第十三次循环,在arr[12]在进行赋值之前,arr[12]并不是一个随机值,而是跟 i 一样,都是值为12。
猜测在数组越界后,当后面为arr[12]开辟的区域是不是与i的地址重复了呢?


为了印证上述提出的猜测,我们可以将i的地址与arr[12]的地址取出来,观察是否为同一个地址。

在这里插入图片描述
如图所示,猜测属实。arr[12]的地址与i的地址为同一个地址。
所以当arr[12]被赋值为0时,i 也被赋值为零,循环条件回到起点,产生死循环。

三、原因

[在这里插入图片描述]
局部数据是储存在栈区中的。
1.栈区的使用习惯是先使用高地址处的空间,再使用低地址处的空间,i 变量先被创建,使用高地址,arr后被创建,使用低地址。(高地址在内存上的数值大,低地址在内存上的数值小,在上图中有所反应)
2.数组随着下标的增长,地址是由低到高变化的。
3.由上面两条可知,当数组越界操作时,数组后面创建的地址就有可能覆盖到 i,就有可能会出现死循环。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值