数组越界导致的错误

文章目录

案例

首先我们来看一段代码

#include<stdio.h>
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\n");
    }
    return 0;
}

大家觉得这段代码的运行结果时什么呢? 相信会有人说数组越界,也会有人认为应该打印

出13个hello,那么真实的结果是什么样的呢? 我们来调试看一下。

首先当 i 从 0 到 9 时,如我们预料一样,arr[0]到arr[9]被置成了0
接着, arr[10],arr[11]也相继被置成了0,但i =12时,我们可以惊奇的发现,i 和arr[12]的值是一样的,难道 i 和arr[12]是占用的相同的内存空间吗? 有读者可能会觉得arr[12]还没有被初始化,那么12有可能只是一个随机值罢了。
那么,我们打开调试里的内存窗口看一看

由此我们可以知道 i 和arr[12] 占用的内存空间就是一样的,接下来我们将arr[12]改成了0,也就是将循环变量 i 改成了0,这样就会无限循环的打印 hello

案例分析

那么为什么 i 和arr[12]的空间是一样的呢?

i 和arr数组都是局部变量,被放在内存的栈区

栈区内存的使用习惯是: 先使用高地址处的空间,再使用低地址处的空间。因此 i 被放置在了相对于数组来说较高的地址处。

数组随着下标的增长,地址是由低到高变化的。

i 和arr数组大致的内存分布情况如下图所示, 图中一个格子代表4个字节

所以,当数组适当越界得情况下,就可能导致越界访问到循环变量i,改变i的值就可能导致死循环。

相信有人会怀疑为什么一定i和arr数组之间就恰好各了两个空格(也就是8个字节)呢?这难道不是巧合吗?

确实,编译器不同,i和arr数组之间所差的字节不同,而在VS编译器下就差8个字节,但是在Linux x86_64 gcc环境下,它们所差的就是4个字节(也就是一个格子)。

该案例也提醒我们以后在写代码时,一定要注意数组越界的情况。

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值