go語言的局部變量在堆上還是棧上?


在討論之前,先看如下代碼:

 1 type treeNode struct {
 2     value int
 3     left, right *treeNode
 4 }
 5 
 6 func createNode(value int) *treeNode {
 7     return &treeNode{value:value}
 8 }
 9 
10 func main() {
11     root := createNode(10)
12     fmt.Println(root)
13 }

上面這段代碼createNode函數返回了一個局部變量的地址給main函數中的root,但是fmt.Println正常打印出來了新建的node的內容。這要是在C++中這么寫,是個很典型的錯誤:返回局部變量的地址,該地址的內容在函數退出后會被自動釋放,因為是在棧上的。

那么go語言的局部變量到底是在棧上還是堆上呢?go語言編譯器會做逃逸分析(escape analysis),分析局部變量的作用域是否逃出函數的作用域,要是沒有,那么就放在棧上;要是變量的作用域超出了函數的作用域,那么就自動放在堆上。所以不用擔心會不會memory leak,因為go語言有強大的垃圾回收機制。這樣可以釋放程序員的內存使用限制,讓程序員關注程序邏輯本身。

 

對於new出來的局部變量,也不是一定就放在堆上,而是根據其是否超出了函數作用域來判斷是否放在堆上還是棧上。這點和C語言很不一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM