This is a rookie question, please bear with me. So the doubt is why f() function points different address. My understanding is the variable v must overwrite the old value.
package main
import "fmt"
var p = f()
func f() *int {
v := 1
return &v
}
func main() {
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(p)
}
//0xc0000140b0
//0xc0000140b8
//0xc0000140e0
//0xc000014098
CodePudding user response:
The compiler detects that v
escapes
the function f
, so it is allocated on the heap. Each call to f
returns a new instance of v
, that's why you see a different address for each call.
CodePudding user response:
To give a simple answer to this
Go looks for variables that outlive the current stack frame and then heap-allocates them
Basically, the variable v escapes the function f stack frame and gets allocated in heap which is why you see different addresses printed everytime.
Read this nice introduction to escape analysis. https://medium.com/a-journey-with-go/go-introduction-to-the-escape-analysis-f7610174e890
Try running escape analysis to see all the variables that got escaped.
go build -gcflags="-m" main.go:
./main.go:7:2: moved to heap: v //points to v := 1
./main.go:12:15: moved to heap: v //points to fmt.Println(f())
./main.go:13:15: moved to heap: v //points to fmt.Println(f())
./main.go:14:15: moved to heap: v //points to fmt.Println(f())
Note that the last fmt.Println(f())
statement is not considered for escaping as value passed to Println is p
which is a global variable so its already in heap and thus doesn't need to escape
.