2013-11-03 91 views
1

假設您有一個int arr [],其中包含10個元素和一個int * ptr。 我認爲以下幾行會導致一個錯誤,但它會打印0作爲存儲在ptr中的值。它是如何計算爲0的?指向數組中的第11個元素,其中有10個元素C

ptr = arr;//ptr currently points to the first element in arr 
ptr = (arr + 10);//points to what would be the llth element in memory for arr 
printf("ptr %p\n", ptr);//this displays where the 11th element would be in memory 
printf("*ptr %i\n", *ptr);//why would this print 0? 

回答

6

存取數組越界是未定義的行爲。這意味着任何事情都可能發生,比如崩潰,或者打印出0或任何其他數字,但事先不能預知會發生什麼。

這就是爲什麼未定義的行爲是如此邪惡,你可能甚至沒有注意到有什麼不對,因爲它似乎正常工作。當您嘗試測試時,您甚至可能會在計算中得到正確的結果,並且下次運行時可能會出現問題。

+0

它是否使用指針算術來解決這個問題呢,還是其他的東西? –

+1

它使用指針算術來獲取地址,並指向結尾的元素是合法的。但是一旦你試圖解引用它,你就會處於未定義的行爲狀態。 –

1

注意ANSI C要求,如果你定義:

SomeType array[10]; 

然後在地址&array[10](相當於array + 10)必須是一個有效的地址。但是,不允許取消引用該有效地址;這樣做會引發未定義的行爲,任何事情都可能發生。也就是說,最常見的行爲是其他變量被讀取,但不能先驗地告訴哪個變量,它可能是函數的返回地址或其他意想不到的東西。

由於這樣做的結果,你可以運行一個循環是這樣的:

SomeType *end = array + 10; 

for (SomeType *src = array; src < end; src++) 
{ 
    ...use `*src` to reference the current row of the array... 
} 

另一個後果是,有什麼可以被放置在可尋址存儲器的最頂端限制。但是,這些問題很少引起人們的關注(除非你正在研究內存非常小的嵌入式微型計算機)。

相關問題