如何在C语言中避免数组越界

  介绍

这篇文章将为大家详细讲解有关如何在C语言中避免数组越界,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

所谓的数组越界,简单地讲就是指数组下标变量的取值超过了初始定义时的大小,导致对数组元素的访问出现在数组的范围之外,这类错误也是C语言程序中最常见的错误之一。

在C语言中,数组必须是静态的。换而言之,数组的大小必须在程序运行前就确定下来。由于C语言并不具有类似Java等语言中现有的静态分析工具的功能,可以对程序中数组下标取值范围进行严格检查,一旦发现数组上溢或下溢,都会因抛出异常而终止程序。也就是说,C语言并不检验数组边界,数组的两端都有可能越界,从而使其他变量的数据甚至程序代码被破坏。

因此,数组下标的取值范围只能预先推断一个值来确定数组的维数,而检验数组的边界是程序员的职责。

一般情况下,数组的越界错误主要包括两种:数组下标取值越界与指向数组的指针的指向范围越界。

数组下标取值越界

数组下标取值越界主要是指访问数组的时候,下标的取值不在已定义好的数组的取值范围内,而访问的是无法获取的内存地址。例如,对于数组int[3],它的下标取值范围是(0,2)(即[0]、[1]与[2])。如果我们的取值不在这个范围内(如[3]),就会发生越界错误。示例代码如下所示:

int  [3];   int  i=0;   (i=0; i<4,我+ +)   {   ,,(我),=,我;   }   (i=0; i<4,我+ +)   {   ,,printf (“[% d]=% d \ n",我[我]);   }

很显然,在上面的示例程序中,访问一个[3]是非法的,将会发生越界错误。因此,我们应该将上面的代码修改成如下形式:

int  [3];   int  i=0;   (i=0; i<3,我+ +)   {   ,,(我),=,我;   }   (i=0; i<3,我+ +)   {   ,,printf (“[% d]=% d \ n",我[我]);   }

指向数组的指针的指向范围越界

指向数组的指针的指向范围越界是指定义数组时会返回一个指向第一个变量的头指针,对这个指针进行加减运算可以向前或向后移动这个指针,进而访问数组中所有的变量。但在移动指针时,如果不注意移动的次数和位置,会使指针指向数组以外的位置,导致数组发生越界错误。下面的示例代码就是移动指针时没有考虑到移动的次数和数组的范围,从而使程序访问了数组以外的存储单元。

int 我;   int  * p;   int  [5];/*数组一的头指针赋值给指针p */p=一个;   (i=0; i<10;我+ +)   {/*指才能针p指向的变量*/* p=我才能+ 10;/*指才能针p下一个变量*/p + +才能;   }

在上面的示例代码中,为循环会使指针p向后移动10次,并且每次向指针指向的单元赋值。但是,这里数一的组下标取值范围是[0,4](即[0]、[1],[2],[3]与[4]),因此,后5次的操作会对未知的内存区域赋值,而这种向内存未知区域赋值的操作会使系统发生错误。正确的操作应该是指针移动的次数与数组中的变量个数相同,如下面的代码所示:

int 我;   int  * p;   int  [5];/*数组一的头指针赋值给指针p */p=一个;   (i=0; i<5,我+ +)   {/*指才能针p指向的变量*/* p=我才能+ 10;/*指才能针p下一个变量*/p + +才能;   }

为了加深大家对数组越界的了解,下面通过一段完整的数组越界示例来演示编程中数组越界将会导致哪些问题。

# define  PASSWORD “123456”;   int 测试(char  * str)   {   int 才能;旗帜;   char 才能;缓冲[7];   国旗=才能比较字符串(str、密码);   拷贝字符串才能(缓冲区,str);   return 才能;旗帜;   }   int 主要(空白)   {   int 才能;标志=0;   char 才能str [1024];   而(1)才能   {才能   ,,,printf(“请输入密码:,“);   ,,,scanf (“% s", str);   ,,,flag =,测试(str);   ,,,如果(国旗)   ,,,{   ,,,,,printf(“密码错误! \ n");   ,,,}   ,,,,,   ,,,,,{   ,,,,,,,printf(“密码正确! \ n");   ,,,,,}   ,,}   return 才能;0;   }

上面的示例代码模拟了一个密码验证的例子,它将用户输入的密码与宏定义中的密码“123456”进行比较。很显然,本示例中最大的设计漏洞就在于 Test() 函数中的 strcpy(buffer,str) 调用。

如何在C语言中避免数组越界