討論一個堆棧越界的問題

咱們先看一個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

圖片描述

相關文章
相關標籤/搜索