《C陷阱和缺陷》一书中一道值得注意的题!!

目录

面试题

请问以下程序运行的结果是什么?为什么?

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

这是我的在不同环境在运行的结果

首先是在vs2017上的运行结果

在这里插入图片描述

首先编译器检查到了这个错误,并且弹出了错误信息

这是我使用微信的拍照翻译工具对这句话进行的解读 运行检查失败 #- 变量’arr ’ r 周围的堆栈被损坏

接下来说说在vc++2010环境的运行结果

在这里插入图片描述

vc++2010的运行结果很明显不同于vs2017的是居然陷入了死循环!!!

接下来我们要对此进行一个分析,是什么原因?

首先我们知道栈的使用习惯是:1、先使用高地址空间,再使用低地址空间 而数组的使用习惯是:1、随着下标的增长,地址是由低到高变化的!

那么这两个结论对于我们的研究有什么关系吗?
答案是有的

在这里插入图片描述

在调试窗口上添加监视观察的是随着循环的不断遍历居然会影响到arr[10],arr[11],arr[12]的值,并且都被置零了,这就很不可思意当然这是在vs2017上的调试测试

大致的把内存图展示给大家

在这里插入图片描述

其实他的原理是
因为都是局部变量而局部变量是存放在栈上的,当数组的地址空间是由低到高,当数组的下标不断的增加,直到到达了arr[12]的时候,在这个地址位置上不仅仅表示的是arr[12]这个元素的地址,他还表示变量i的地址
而当arr[12] = 0指令的执行,伴随着i的值也会被改变 为0,那么0 < 12循环永远不会终止

原因是因为arr[9]和arr[12]之间空了两个整形,恰好这个原因导致他们之间产生了关联关系

1. 另外注意:1、vc++2010上是空两个整形
2、linux上是空一个整形
3、在vs2017上能被直接检查出来

  • 15
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱生活,爱代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值