咱們先看一個linux下的C代碼,分析一下運行結果:html
1 int main(int argc, char* argv[]) { 2 int i = 0; 3 int arr[3] = {0}; 4 for(; i<=3; i++) { 5 arr[i] = 0; 6 printf("hello world\n"); 7 } 8 return 0; 9 }
顯然,因爲數組越界致使行爲未知?
其實,行爲雖然非法,但並非未知或者由於非法訪問而退出。linux
咱們知道,在 C 語言中,只要不是訪問受限的內存,全部的內存空間都是能夠自由訪問的。根據數組尋址方式(線性連續),a[3] 也會被定位到某塊不屬於數組的內存地址上,而這個地址正好是存儲變量 i 的內存地址,那麼 a[3]=0 就至關於 i=0,因此就會致使代碼無限循環。數組
看到這裏,應該還有不少疑問,可是仍是請先思考一下。函數
咱們再進一步,函數體內的局部變量存在棧上,且是連續壓棧。在Linux進程的內存佈局中,棧區在高地址空間,從高向低增加。變量 i 和 arr 在相鄰地址,且 i 比 arr 的地址大,因此 arr 越界正好訪問到 i。固然,前提是 i 和 arr 元素同類型,不然那段代碼還是未決行爲。佈局
看到這裏,應該大致的緣由已經說清楚了,那麼若是想了解的更加深刻,我給你們推薦一個連接:GCC 中的編譯器堆棧保護技術
最後,給你們再留一個思考:若是 arr[3] 變成 arr[5],結果是否還會無限循環呢?spa