如下代碼測試環境:vs2019c++
執行這麼一段代碼,看看會發生什麼:函數
int arr[5] = { 0 }; int main() { arr[5] = 1; }
毫無疑問,會報錯,由於訪問越界了。測試
再看看另外一段代碼:操作系統
int arr[5] = { 0 }; int main() { arr[5] = 1; }
與上面的代碼相比幾乎沒什麼差異,僅僅把arr的定義和初始化搬到了函數外面,但執行程序卻沒有出錯。.net
相似的還有這麼一段代碼:code
int main() { static int arr[5] = { 0 }; arr[5] = 1; }
一樣也能執行成功,那麼這是爲何呢?blog
如下這段話摘自內存
在
C++
中內存分爲5個區,分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。
堆:堆是操做系統中的術語,是操做系統所維護的一塊特殊內存,用於程序的內存動態分配,C
語言使用malloc
從堆上分配內存,使用free
釋放已分配的對應內存。
棧:在執行函數時,函數內局部變量的存儲單元均可以在棧上建立,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,可是分配的內存容量有限。
自由存儲區:自由存儲區是C++
基於new
操做符的一個抽象概念,凡是經過new
操做符進行內存申請,該內存即爲自由存儲區。
全局/靜態存儲區:這塊內存是在程序編譯的時候就已經分配好的,在程序整個運行期間都存在。例如全局變量,靜態變量。
常量存儲區:這是一塊比較特殊的存儲區,他們裏面存放的是常量(const)
,不容許修改。get
上面的問題涉及到兩個區:棧和全局/靜態存儲區。編譯
基於以上結果,我有個不成熟的小推測:
int arr[5]
,那麼系統就必定給我5*4(32位系統下)個字節的空間,系統不容許我訪問超過這個空間的地址上的數據。int arr[5]
時,系統給我返回arr
的首地址,我不只能夠根據這個首地址去訪問20個字節的內容,還能夠訪問這二十個字節之外的內容。