数组越界怎么处理 数组越界

来自公众号:技术让梦想更伟大
作者:李肖遥
所谓的数组越界,简单地讲就是指数组下标变量的取值超过了初始定义时的大小,导致对数组元素的访问出现在数组的范围之外,这类错误也是 C 语言程序中最常见的错误之一 。
在 C 语言中,数组必须是静态的 。换而言之,数组的大小必须在程序运行前就确定下来 。由于 C 语言并不具有类似 Java 等语言中现有的静态分析工具的功能,可以对程序中数组下标取值范围进行严格检查,一旦发现数组上溢或下溢,都会因抛出异常而终止程序 。也就是说,C 语言并不检验数组边界,数组的两端都有可能越界,从而使其他变量的数据甚至程序代码被破坏 。
因此,数组下标的取值范围只能预先推断一个值来确定数组的维数,而检验数组的边界是程序员的职责 。
一般情况下,数组的越界错误主要包括两种:数组下标取值越界与指向数组的指针的指向范围越界 。

数组越界怎么处理  数组越界

文章插图

数组下标取值越界数组下标取值越界主要是指访问数组的时候,下标的取值不在已定义好的数组的取值范围内,而访问的是无法获取的内存地址 。例如,对于数组int a[3],它的下标取值范围是[0,2](即a[0]、a[1] 与 a[2]) 。如果我们的取值不在这个范围内(如 a[3]),就会发生越界错误 。示例代码如下所示:
int a[3];
int i=0;
for(i=0;i<4;i++)
{
a[i] = i;
}
for(i=0;i<4;i++)
{
printf("a[%d]=%d\n",i,a[i]);
}
很显然,在上面的示例程序中,访问 a[3] 是非法的,将会发生越界错误 。因此,我们应该将上面的代码修改成如下形式:
int a[3];
int i=0;
for(i=0;i<3;i++)
{
a[i] = i;
}
for(i=0;i<3;i++)
{
printf("a[%d]=%d\n",i,a[i]);
}
数组越界怎么处理  数组越界

文章插图

指向数组的指针的指向范围越界指向数组的指针的指向范围越界是指定义数组时会返回一个指向之一个变量的头指针,对这个指针进行加减运算可以向前或向后移动这个指针,进而访问数组中所有的变量 。但在移动指针时,如果不注意移动的次数和位置,会使指针指向数组以外的位置,导致数组发生越界错误 。下面的示例代码就是移动指针时没有考虑到移动的次数和数组的范围,从而使程序访问了数组以外的存储单元 。
int i;
int *p;
int a[5];
/*数组a的头指针赋值给指针p*/
p=a;
for(i=0;i<10;i++)
{
/*指针p指向的变量*/
*p=i+10;
/*指针p下一个变量*/
p++;
}
在上面的示例代码中,for 循环会使指针 p 向后移动 10 次,并且每次向指针指向的单元赋值 。但是,这里数组 a 的下标取值范围是[0,4](即a[0]、a[1]、a[2]、a[3] 与 a[4]) 。因此,后 5 次的操作会对未知的内存区域赋值,而这种向内存未知区域赋值的操作会使系统发生错误 。正确的操作应该是指针移动的次数与数组中的变量个数相同,如下面的代码所示:
int i;
int *p;
int a[5];
/*数组a的头指针赋值给指针p*/
p=a;
for(i=0;i<5;i++)
{
/*指针p指向的变量*/
*p=i+10;
/*指针p下一个变量*/
p++;
}
为了加深大家对数组越界的了解,下面通过一段完整的数组越界示例来演示编程中数组越界将会导致哪些问题 。
1 #define PASSWORD "123456"
2 int Test(char *str)
3{
4 int flag;
5 char buffer[7];
6 flag=strcmp(str,PASSWORD);
7 strcpy(buffer,str);
8 return flag;
9}
10 int main(void)
11{
12 int flag=0;
13 char str[1024];
14 while(1)
15 {
16 printf("请输入密码: ");
17 scanf("%s",str);
18 flag = Test(str);
19 if(flag)
20 {
21 printf("密码错误!\n");
22 }
23 else
24 {
25 printf("密码正确!\n");
26 }
27 }
28 return 0;
29}
上面的示例代码模拟了一个密码验证的例子,它将用户输入的密码与宏定义中的密码123456进行比较 。很显然,本示例中更大的设计漏洞就在于 Test() 函数中的strcpy(buffer,str)调用 。
由于程序将用户输入的字符串原封不动地复制到 Test() 函数的数组char buffer[7]中 。因此,当用户的输入大于 7 个字符的缓冲区尺寸时,就会发生数组越界错误,这也就是大家所谓的缓冲区溢出Buffer overflow漏洞 。

推荐阅读