Search code examples
gopointersescape-analysis

Go escape analysis, with var(s) declared as pointers


func main() {
 var cs CustomStruct
 r := []byte{.......}
 err:=proto.Unmarshal(r, &cs)
 if err!=nil {
    panic(err)
  } 
}

When I run go build -gcflags="-m" ./... , I get

moved to heap: CustomStruct

But with a small change, it does not get moved to the heap:

func main() {
 var cs *CustomStruct
 r := []byte{.......}
 err:=proto.Unmarshal(r, cs)
 if err!=nil {
    panic(err)
  } 
}

Now when I run the escape-analysis command, it doesn't say that CustomStruct gets moved to the heap. What exactly is going on, here?


Solution

  • Since the address of cs is sent to a function and that function may spawn goroutines that may hold a reference to cs after the function returns, it is moved to heap.

    In the second case, cs is a pointer. There is no need to move the pointer itself to the heap, because that the function Unmarshal can refer to is the object pointed to by cs, not cs itself. You didn't show how cs is initialized, so this piece of code will fail, however if you initialize cs to point to a variable declared in that function, that object will likely end up in the heap.