2011-12-19 59 views
0

我碰到這個代碼就意外:數組分配導致終端掛

#include<stdio.h> 
int main() 
{ 
    int i; 
    int array[3]; 
    for(i=0;i<=3;i++) 
     array[i]=0; 
    return 0; 
} 

在運行這段代碼我的終端被吊死 - 代碼沒有終止。

當我用替換2代碼成功運行並終止沒有問題。 在C中沒有對數組進行綁定檢查,那麼導致它不終止的上述代碼有什麼問題?

平臺 - Ubuntu的10.04 編譯器 - GCC

+2

0和3之間有4個數字。但是,數組聲明只有3個元素。 – Dave 2011-12-19 17:35:24

+0

我知道....我的問題是爲什麼這段代碼沒有終止? – 2011-12-19 17:37:00

+0

我也想知道是什麼原因造成的。在任何行爲良好的系統中,試圖編寫其他人的存儲位置會導致程序異常終止,不是嗎? – 2011-12-19 17:41:18

回答

2

僅僅因爲沒有綁定檢查並不意味着寫入越界沒有任何後果。這樣做會調用未定義的行爲,所以不知道會發生什麼。

這次,在這個編譯器上,在這個架構上,當你寫入到array[3]時,實際上你將i設置爲零,因爲我被定位在堆棧的array之後。

+0

相同,我認爲你是正確的......你可以看到使用gdb。 – 2011-12-19 17:45:57

2

您的代碼讀取超出約束陣列,並引起未定義行爲

當您聲明大小爲3的數組時。有效索引範圍從02
雖然您的循環從0運行到3

如果您訪問超出數組有效範圍的任何內容,那麼它是未定義的行爲,您的程序可能會掛起或崩潰或顯示任何行爲。在這種情況下,c標準沒有強制任何特定的行爲。

當你說C沒有做邊界檢查時,實際上意味着程序員有責任確保他們的程序不能訪問超出分配數組的範圍,並且不能這樣做會導致所有安全下注都被關閉,行爲。

0

array的最高有效索引是2。通過該索引寫入調用未定義的行爲。

你看到的是未定義行爲的體現。

對比這與以下兩個片段,這兩者都是正確的:

/* 1 */ 
int array[3]; 
for(i=0;i<3;i++) { array[i] = 0; } 

/* 2 */ 
int array[4]; 
for(i=0;i<4;i++) { array[i] = 0; } 
0

你聲明的大小3,這意味着數組(0,1,2是有效索引)

,如果你嘗試設置0到一些內存的位置是不是我們意外(一般稱爲UB未定義行爲)的事情可能發生

1
int array[3]; 

這聲明的3個整數的數組,具有索引0,1,和2。

for(i=0;i<=3;i++) 
    array[i]=0; 

此寫入整數到陣列中,在索引0,1,2,和3。這是一個問題。

這裏沒有人可以確切地知道你在看什麼 - 你甚至沒有指定你正在工作的平臺。我們所能說的只是代碼被破壞了,而這會導致你看到的任何結果。一種可能性是我在數組之後存儲,所以當你做數組[3] = 0時,你最終將我設置回0。但這只是一個猜測。

0

數組中的元素編號爲0到(n-1)。你的陣列有3個點,但正在初始化4個位置(0,1,2,3)。通常情況下,你會讓你的循環說我< 3,以便你的號碼匹配,但你不會超過數組的上限。