golang 數組的一些自問自答

所有程式碼基於Go-1.17。一些研究Go數組的自問自答,可以考慮作為面試題。

問題:靜態存儲區是什麼?和堆/棧有什麼區別?

回答:

可以參考下列圖

堆上存放new產生的大塊記憶體

棧上存放的是程式運行的時候使用的局部變數記憶體

程式碼段和數據段可以統一稱為靜態存儲區

程式碼段存放的就是程式的二進位文件

數據段存放的包含三個部分:

  • 只讀數據段
    • 一般是const修飾的變數,不需要修改的
  • 已初始化的讀寫數據段
    • 已初始化的全局變數
    • 已經初始化的靜態局部變數
  • 未初始化段
    • 未初始化的全局變數
    • 未初始化的靜態變數

問題:數組的初始化是在棧上,還是在數據段上的?

回答:

如果是非字面量數組類型,會在棧上初始化

如果是字面量類型:

當元素少於或者等於4個的時候,會直接將數組元素在棧上初始化

當元素大於4個的時候,會在數據段初始化,在使用的時候,複製到棧上

具體可以參考

cmd/compile/internal/walk/complit.go的 anylit

問題: 數組的結構是什麼樣子的?

數組在記憶體中是一段連續的記憶體。

它的類型為:

裡面存放了Bound,元素個數,和Elem 單個元素的類型。

問題:go訪問數組的下標越界是運行時候發現的還是編譯期發現的?

回答:

兩個階段都有可能,對於可以靜態檢測出來的,在編譯器就會報錯。

比如程式碼:

具體使用的是 cmd/compile/internal/typecheck/expr.go 的 tcIndex 方法

但是如果是使用變數下標來訪問,就只能在運行期間來判斷是否越界。通過彙編碼大致能看到最後調用panicIndex

參考

//blog.csdn.net/chen1083376511/article/details/54930191

Tags: