学科分类
目录
C语言

数组边界

在前面章节讲解数组索引时,如果一个数组中有n个元素,数组索引就为0~(n-1),在为数组赋值或访问数组元素时,不能超过这个范围边界。如果超出这个边界,编译器就会报错或得到无法预期的数据。

定义如下数组:

int arr[5] = { 1,2,3,4,5 };

在上述代码中,数组arr的索引范围为0~4,如果超过范围访问不存在的元素,如arr[-1]、arr[6],就会得到一个无法预期的数据,即垃圾数据。在这个过程中,编译器虽然不会报错,但会发出警告。例如,访问arr[5]时,Visual Studio 2019发出的警告如图1所示。

图1 访问arr[5]警告

由图1可知,当读取arr[5]时,编译器警告:索引“5”超出了“0”至“4”的有效范围。

C语言是不安全的编程语言,访问数组时不进行边界检查,当访问超出范围的数组元素时,虽然编译器会发出警告,但并不会阻止程序运行,程序会按数组步长依次向后(向前)读取内存,如图2所示。

图2 超范围访问数组元素内存图解

在图2中,数组arr大小为5,编译器为数组分配5个连续的int类型数据存储单元,当超出范围访问arr[5]时,编译器会根据数组的规则,移动一个步长连续访问arr[4]后面的4字节内存空间,但是这个内存空间并不是分配给数组arr的,访问该内存空间时,会获取未知数据。同理,当访问arr[-1]时,编译器会按数组规则向前读取一块内存空间。需要注意的是,如果超范围访问的空间正好在被其他程序使用,那么程序在访问时就会出错。

超出范围访问数组元素,编译器只会发出警告,但是如果超出范围对元素赋值,程序会抛出异常,例如对arr[5]进行赋值,再访问,示例代码如下:

arr[5] = 6;        //超出数组范围赋值
printf("%d\n", arr[5]);  //访问

执行上述代码,程序能够成功赋值且成功访问到arr[5]元素的值6,但执行过程中会抛出异常,如图3所示。

图3 抛出异常

由图3可知,超出范围赋值并访问数组元素,会抛出异常,提示运行时检查失败#2-围绕变量“arr”的堆栈已崩溃。

在使用数组时,读者一定要注意作好边界检查,不要超出范围去访问数组元素,以免程序发生不可预知的错误。

点击此处
隐藏目录