2014-10-01 139 views
-8

此處數組的下標超出範圍。超出範圍的下標

int a[10], i; 
for (i = 1; i <= 10; i++) 
a[i] = 0; 
printf("India"); 

輸出是一個無限循環並且printf語句不會被執行。這裏是寫在K N王的東西:

當我達到10時,程序將0存儲到[10]中。但是[10]不存在。 因此0在[9]之後立即進入內存。如果變量i碰巧在內存中遵循 a [9](可能是這種情況),那麼我將重置爲O.導致 循環重新開始。

任何人都可以解釋它嗎?

+5

數組索引是基於**零**的,即在你的例子中,0到9,而不是1到10. – isedev 2014-10-01 15:31:20

+0

爲什麼它是無限循環 – 2014-10-01 15:32:34

+0

告訴我原因 – 2014-10-01 15:34:57

回答

3

這將形成一個無限循環的想法是基於一個關於如何將變量放置在內存中的假設。特別是,它假定因爲i定義爲之後立即在a之後,它也會在a之後立即分配到內存中。

這當然不能保證,但它同樣肯定會發生。如果是,則寫入a[10]實際上可能會覆蓋i。由於它將0寫入不存在的a[10],因此實際上將0寫入i。然後當循環中的條件檢查i <= 10時,這是真的,因此循環繼續 - 並且每次i變爲10時,在之前它立即被0 覆蓋,因此循環條件被評估,所以循環從開始。

就C或C++標準而言,它只是未定義的行爲 - 當代碼寫入數組末尾時任何東西都可能發生。它可能會做某人期望的事情,或者可能會做一些完全不同的和不相關的東西,完全不會有意義。編譯器可以自由發出在這種情況下幾乎完成任何事情的代碼(或者它可以將它診斷爲錯誤,並且根本不會發出任何代碼)。

給什麼符合行爲可能是一些想法:GCC的早期版本有代碼來檢測的實現定義的特定情況下(非常喜歡不確定的行爲,除了實施必須以文件它做什麼) 。在這種情況下,記錄的行爲相當複雜。編譯器將嘗試做以下每一項爲了(在那個成功的第一個停止):

  1. 運行nethack(遊戲)
  2. 運行流氓(另一場比賽)
  3. 啓動Emacs,並讓它執行河內模擬的塔樓
  4. 打印出「你正處在一個曲折的小段落的迷宮中,都一樣」。

我可以得到這些有點不對的順序(這是一個很長時間前),但你的想法。結果有什麼也沒有與一個合理的人可能會期望的任何事情。

+0

+1對於各種UB尤其是「你正處在一個曲折的小段落迷宮中,一切都一樣」。嗯,一個空洞的聲音說「Plugh」。 – chux 2014-10-01 17:40:20