數組越界怎么處理 數組越界

來自公眾號:技術讓夢想更偉大
作者:李肖遙
所謂的數組越界,簡單地講就是指數組下標變量的取值超過了初始定義時的大小,導致對數組元素的訪問出現在數組的范圍之外,這類錯誤也是 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漏洞 。

推薦閱讀