c语言---访问越界之后死循环的原因

目录

  • 死循环的概念
  • 环境
  • 题目代码
  • 运行结果
  • 对代码发生情况进行解释
  • 对i的地址和arr[12]地址一样的解释
  • 注意
  • 总结

死循环的概念

简单来说,死循环就是指无法靠自身的控制终止循环,在编程中,则是靠自身控制无法终止的程序。即在某一时刻,当程序遇到循环判断语句使条件一直成立时,导致此时该程序始终在执行,跳不出循环,程序不能自己正常结束。

环境

在这里插入图片描述

在VS2022、X86、Debug 的环境下,编译器不做任何优化的话,看看下⾯代码执⾏的结果

题目代码

这个代码严重依赖环境。

#include 
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("牛逼\n");
	}
	return 0;
}

运行结果

c语言---访问越界之后死循环的原因_第1张图片
在这里可以看到一直在打印牛逼这两个字,这就是进入了程序死循环。

对代码发生情况进行解释

对这个代码进行调试按F10走起,到下面这里
c语言---访问越界之后死循环的原因_第2张图片
可以看到现在已经打印了10个牛逼
c语言---访问越界之后死循环的原因_第3张图片
然后我们再继续按F10看看会怎么样呢?
c语言---访问越界之后死循环的原因_第4张图片
可以看到i的值也跟着arr[12]一起变成0了。那么为什么i也会跟着改呢?但凡是不是i不改的话,i是不是通过i++,然后就变成13了就跳出了这次循环。但是并没有这样,那为什么看到i的值也跟着arr[12]一起变成0了呢?难道i和arr[12]在同一块空间?
为了验证这个问题,我们取i的地址和arr[12]的地址,
c语言---访问越界之后死循环的原因_第5张图片

可以看出i的地址和arr[12]的地址一模一样,这就说明,改arr[12],i也会跟着改。然后又重新开始,这个i永远也不可能等于13,然后就出现了程序死循环。

对i的地址和arr[12]地址一样的解释

1.栈区内存的使⽤习惯是从⾼地址向低地址使⽤的,所以变量i的地址是
较⼤的。arr数组的地址整体是⼩于i的地址。
2. 数组在内存中的存放是:随着下标的增⻓,地址是由低到⾼变化的。所以根据代码,就能理解为什么是左边的代码布局了。如果是左边的内存布局,那随着数组下标的增⻓,往后越界就有可能覆盖到i,这样就可能造成死循环的。这⾥肯定有人有疑问:为什么i和arr数组之间恰好空出来2个整型的空间呢?这⾥确实是巧合,在不同的编译器下可能中间的空出的空间⼤⼩是不⼀样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以的不同的编译器之间就有差异了。所以这个题⽬是和环境相关的。
c语言---访问越界之后死循环的原因_第6张图片
从这个理解我们能够体会到调试的重要性,只有调试才能观察到程序内部执⾏的细节,就像医⽣给病⼈做B超,CT⼀样。

注意

栈区的默认的使⽤习惯是先使⽤⾼地址,再使⽤低地址的空间,但是这个具体还是要编译器的实现,⽐如:
在VS上切换到X64,这个使⽤的顺序就是相反的,在Release版本的程序中,这个使⽤的顺序也是相反的。
用VS2022、X64、Debug 的环境运行一遍:
在这里插入图片描述
运行结果
c语言---访问越界之后死循环的原因_第7张图片
这个代码换个环境就不行了,就不会出现程序死循环的现象。

总结

#include 
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("牛逼\n");
	}
	return 0;
}

这个题目代码是在环境(VS2022、X86、Debug)的环境下会出现程序死循环,再次强调这个题目代码强烈依赖环境.。
c语言---访问越界之后死循环的原因_第8张图片
欧耶!!!!!我学会啦!!!!!!!!

你可能感兴趣的:(#,c语言,c语言)