Initializing objects in GoLang - Heap/stack does that concept exist?

Viewed 162

I just started with GoLang. I have noticed there are some initializations like this

agentUi := &f.Foo{
        Reader:      os.Stdin,
        Writer:      os.Stdout,
        ErrorWriter: os.Stderr,
    }

Coming from a c++ background , I am under the impression the reason above was done because the developer wanted to create a pointer agentUi instead of an object where he could have done something like this

agentUi := f.Foo{
        Reader:      os.Stdin,
        Writer:      os.Stdout,
        ErrorWriter: os.Stderr,
    }

so basically making sure that the object is still valid after the scope ends.In short create the object on the heap instead of the stack. Is that correct ?

1 Answers

Go does not allow direct control over where the memory you use is allocated.

If you aren't using references, the memory is allocated from the stack.

If you are passing references around, the compiler does escape analysis in order to try to allocate from the stack, but failing that, the memory is allocated on the heap.

You can use -gcflags '-m -l' to see escape analysis for your program.

go run -gcflags '-m -l' main.go

For instance, verifying escape analisys on the program below.

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    fmt.Printf("%v\n", work())
}

type Foo struct {
    Reader      io.Reader
    Writer      io.Writer
    ErrorWriter io.Writer
}

func work() *Foo {
    agentUi := &Foo{
        Reader:      os.Stdin,
        Writer:      os.Stdout,
        ErrorWriter: os.Stderr,
    }
    return agentUi
}

Output:

$ go run -gcflags '-m -l' main.go
# command-line-arguments
./main.go:20:13: &Foo{...} escapes to heap
./main.go:10:12: ... argument does not escape
&{0xc00000e010 0xc00000e018 0xc00000e020}
Related