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

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

一、引入

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

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

运行结果:

如下图:代码死循环

二、代码缺陷

上述代码有两个问题:

  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终结者

学会发现问题,解决问题并且避免出现问题是一名合格程序员的基本素养。这就要求我们要掌握一定的调试技巧,养成良好的编程习惯。


相关文章
|
存储 Cloud Native Linux
C++ 如何避免野指针
C++ 如何避免野指针
|
7月前
|
C语言
C语言中如何避免循环死循环
C语言中如何避免循环死循环
323 1
|
7月前
|
存储 编译器 C语言
C陷阱:数组越界遍历,不报错却出现死循环?从内存解析角度看数组与局部变量之“爱恨纠葛”
在代码练习中,通常会避免数组越界访问,但如果运行了这样的代码,可能会导致未定义行为,例如死循环。当循环遍历数组时,如果下标超出数组长度,程序可能会持续停留在循环体内。这种情况的发生与数组和局部变量(如循环变量)在内存中的布局有关。在某些编译器和环境下,数组和局部变量可能在栈上相邻存储,数组越界访问可能会修改到循环变量的值,导致循环条件始终满足,从而形成死循环。理解这种情况有助于我们更好地理解和预防这类编程错误。
162 0
|
7月前
|
存储 编译器 C语言
关于数组越界却不会报错
关于数组越界却不会报错
|
7月前
|
并行计算 安全 开发者
避免Python多线程中的常见陷阱与错误
避免Python多线程中的常见陷阱与错误
104 1
数组越界死循环问题!
数组越界死循环问题!
56 0
|
编译器 C语言 C++
数组越界访问打印后为什么会陷入死循环
数组越界访问打印后为什么会陷入死循环
97 0
|
编译器 C语言 C++
C语言数组越界造成的死循环例子,当你得到了这个意想不到的结果的时候,你肯定不知道为什么,看你还敢不敢越界访问数组了
C语言数组越界造成的死循环例子,当你得到了这个意想不到的结果的时候,你肯定不知道为什么,看你还敢不敢越界访问数组了
124 0
|
编译器 C语言
《C陷阱与缺陷》之“语义”陷阱——数组越界导致的程序死循环问题
《C陷阱与缺陷》之“语义”陷阱——数组越界导致的程序死循环问题
149 0
如何避免数组下标越界
数组下标越界真的是开发过程中的痛,除了在开发过程中各种判断是否设置,是否为空,还有其他优雅的办法解决吗?
146 0