nice2016校招笔试题(西安)例题讲解

在Linux x86 64 gcc环境下,下面的程序会出现什么问题?运行结果是什么?为什么?(10分)

int main(int argc,char*argv[])
{
long i;
long a[16];
for(i=0;i<=17;i++)
{
a[i]=0;
printf(“%d”,i);
}
return 0;
}

运行结果:出现了死循环,即在屏幕上不停的打印i(0~16)的值。

出现以上结果的原因是什么,我们再来看一道相似的例题(在VS2019编译器)

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[10] = { 0 };
    for (i = 0; i <= 12; i++)
    {
        arr[i] = 0;
        printf("hehe\n");
    }
    return 0;
}

运行结果:出现了死循环,即在屏幕上不停的打印"hehe"。

理由:

1. 栈区内存的使用习惯是从高地址向低地址使用的,所以变量i的地址是较大的。arr数组的地址整体是小于i的地址。
2. 数组在内存中的存放是:随着下标的增长,地址是由低到高变化的。所以根据代码,就能理解为什么是上边的代码布局了。 如果是上边的内存布局,那随着数组下标的增长,往后越界就有可能覆盖到i,这样就可能造成死循环的。
这里肯定有同学有疑问:为什么i和arr 数组之间恰好空出来2个整型的空间呢?这里确实是巧合,在不同的编译器下可能中间的空出的空间大小是不一样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以的 不同的编译器之间就有差异了。所以这个题目是和环境相关的。
vc 6.0 中i和arr是连续的,在gcc编译器中,i和arr之间有一个空间。

如果说arr和 i 之间有多余的空间,那么arr数组适当的越界就有可能覆盖到 i ,覆盖到 i, arr[12]的地址就和 i 的地址恰巧一样了,也就是占用同一个空间,arr[12]=0 ,  i也就等于0了,从而实现死循环。

虽然此程序越界访问了,但是由于程序进入了死循环,所以不会报错,因为根本来不及报错就进入死循环了,死循环会掩盖程序中的某些错误。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

你好,赵志伟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值