• C陷阱——数组越界引发的死循环问题


    一、引入

    下面的程序在VS编译器会出现什么问题?运行结果是什么?为什么?

    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:

    如下图:代码死循环

    在这里插入图片描述

    二、代码缺陷

    上述代码有两个问题:

    1. 数组访问越界
    2. 死循环

    三、为什么会死循环?

    1、i和arr都是局部变量,在内存中局部变量都是存储在栈区的。

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

    3、栈区的内存规定:先使用高地址处的空间,再使用低地址处的空间。

    根据上述代码可知,程序会先在栈区中高地址处为变量i开辟空间,再在栈区中由高到低依次为数组arr开辟空间

    如下图👇

    通过调试我们可以在内存中观察到如下变化:

    for循环中,i 的内容是从0,一直增加到12,而数组只有10个空间,因此会越界,每次访问arr数组i号位置时,都会将该位置内容设置为0,当访问到arr[12]时,也会将该位置内容设置为0,而位置恰好为i的位置,即arr[12]恰巧将i设置为0,因此造成死循环。

    四、补充说明

    上述代码在不同的编译器中具有不同的效果,并且与运行环境有关。

    • 在VS2013/2019/2022的x86环境中,i和arr间相隔两个整形。即i<=12就死循环
    • 在gcc中间空相隔一个整形。即i<=11就死循环
    • 在VC6.0中间没有多余的空间。即i<=10就死循环

    五、总结

    在写代码的时候我们可能会遇到各种各样的问题:语法错误、编译错误、运行错误……
    但是我们在制造Bug的同时也要努力成为一名 Bug终结者
    学会发现问题,解决问题并且避免出现问题是一名合格程序员的基本素养。这就要求我们要掌握一定的调试技巧,养成良好的编程习惯。

  • 相关阅读:
    力扣刷题第二十三天--栈与队列
    框架体系——Spring
    js字符串的删除和修改
    【战斗吧,青春!】
    【项目管理】DBClient
    【毕设级项目】基于AI技术的多功能消防机器人(完整工程资料源码)
    点云欧式聚类快速了解
    解析正则表达式的底层实现原理
    Springboot知识点必知必会(一)
    素问·金匮真言论原文
  • 原文地址:https://blog.csdn.net/LEE180501/article/details/126186774