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、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终结者
学会发现问题,解决问题并且避免出现问题是一名合格程序员的基本素养。这就要求我们要掌握一定的调试技巧,养成良好的编程习惯。

到此这篇关于C语言数组越界引发的死循环问题解决的文章就介绍到这了,更多相关C语言数组越界内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解C语言数组越界及其避免方法

    所谓的数组越界,简单地讲就是指数组下标变量的取值超过了初始定义时的大小,导致对数组元素的访问出现在数组的范围之外,这类错误也是 C 语言程序中最常见的错误之一. 在 C 语言中,数组必须是静态的.换而言之,数组的大小必须在程序运行前就确定下来.由于 C 语言并不具有类似 Java 等语言中现有的静态分析工具的功能,可以对程序中数组下标取值范围进行严格检查,一旦发现数组上溢或下溢,都会因抛出异常而终止程序.也就是说,C 语言并不检验数组边界,数组的两端都有可能越界,从而使其他变量的数据甚至程序代码

  • 浅析C语言编程中的数组越界问题

    因为C语言不检查数组越界,而数组又是我们经常用的数据结构之一,所以程序中经常会遇到数组越界的情况,并且后果轻者读写数据不对,重者程序crash.下面我们来分析一下数组越界的情况: 1) 堆中的数组越界 因为堆是我们自己分配的,如果越界,那么会把堆中其他空间的数据给写掉,或读取了其他空间的数据,这样就会导致其他变量的数据变得不对,如果是一个指针的话,那么有可能会引起crash 2) 栈中的数组越界 因为栈是向下增长的,在进入一个函数之前,会先把参数和下一步要执行的指令地址(通过call实现)压栈,

  • C语言陷阱与缺陷之数组越界访问详解

    目录 1.问题引入 2.问题分析 (1)理论分析 (2)调试验证 总结 1.问题引入 一道经典的笔试题来了,请做好准备!!! 试问以下代码在Visual studio 2019环境下执行结果?原因? #include <stdio.h> int main() { int i = 0; int arr[10] = {0}; for(i=0; i<=12; i++) { arr[i] = 0; printf("Hello World!\n"); } return 0; }

  • 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; } 运行结果: 如下图:代码死循

  • .NET下模拟数组越界的方法详解

    前言 前面一篇文章提到过 数组越界行为,虽然编译器为我们做了大量的检查工作让我们避免这些错误. 但是我觉得还是有必要模拟一下数组越界,感受一下这个错误. 那么对于.NET来说我们怎么来模拟数组越界呢? 一. [VS] 项目 -> 右击 -> 属性 -> 生成 -> (勾选)允许不安全代码 二.测试代码 unsafe private static void OutOfIndexMini() { int* i = stackalloc int[1]; i[0] = 0; //i[0]

  • C/C++ 避免数组越界的方法

    所谓的数组越界,简单地讲就是指数组下标变量的取值超过了初始定义时的大小,导致对数组元素的访问出现在数组的范围之外,这类错误也是 C 语言程序中最常见的错误之一. 在 C 语言中,数组必须是静态的.换而言之,数组的大小必须在程序运行前就确定下来.由于 C 语言并不具有类似 Java 等语言中现有的静态分析工具的功能,可以对程序中数组下标取值范围进行严格检查,一旦发现数组上溢或下溢,都会因抛出异常而终止程序.也就是说,C 语言并不检验数组边界,数组的两端都有可能越界,从而使其他变量的数据甚至程序代码

  • java 数组越界判断和获取数组长度的实现方式

    目录 1. 背景介绍 2. 原始java代码 3. java代码对应的反编译字节码 4. jvm实现分析 4.1 获取数组长度arraylength指令核心代码分析 4.2 获取数组元素iaload指令分析 5. 小结一下 java 数组越界问题 1. 背景介绍 java中的数组比c语言中的数组,多了两个很重要的功能 当索引越界时, 会自动抛出ArrayIndexOutOfBoundsException, 避免一错再错 另一个很重要的方法是获取数组长度 这两个功能都不是通过java代码层面实现的

  • C语言数组详细介绍

    目录 什么是数组 一维数组 二维数组 数组越界 数组名 结尾 什么是数组 数组(Array)是一种用来存储同一种类型的集合,是一种有序的线性结构表.并且数组元素的地址是连续的. 数组最大的优点就是支持随机访问,当想访问数组的某个数时,只需要找到数组的对应下标就可以直接找到该数组对应元素.但是数组也有相应的缺点,那就是数组的元素个数和数组空间大小在创建时就已经被固定死了,如果数组的空间没有使用完也会造成空间浪费,并且因为数组的地址是连续的,这本应该是一个优点的,但是这导致数组在进行删除或增加元素时

  • C语言数组全面总结梳理

    目录 一,一维数组 1.创建和初始化 2.使用下标访问 3.在内存中的存储 二,二维数组 1.创建和初始化 2.使用下标访问 3.在内存中的存储 三,越界问题 数组(array)是由一系列类型相同的元素构成. 一般形式: 类型     数组名  [常量表达式] 一,一维数组 1.创建和初始化 创建一堆相同元素的集合,以整型为例: //创建大小为8的整型数组 int arr1[8]; // []里面应放常量,因此若: int num=8; //则有: arr2[num]; num为变量,创建失败

  • C语言数组超详细讲解上

    目录 前言 1.一维数组的创建和初始化 1.1 一维数组的创建 1.2 一维数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 2.二维数组的创建和初始化 2.1 二维数组的创建 2.2 二维数组的初始化 2.3 二维数组的使用 2.4 二维数组在内存中的存储 3.数组越界 4.数组作为函数参数 4.1 冒泡排序函数的错误设计 4.2 数组名是什么? 4.3 对数组名的用法进行总结 4.4 冒泡排序函数的正确设计 总结 前言 本文主要介绍数组相关的内容,主要内容包括: 一维数组

随机推荐