1

I'm learning Go and have a C/C++ background. In the following example, is it safe to append the address of a into slice? When I run this example, the correct value (2) is printed, but wanted to be sure. If this is wrong, how should I do it?

func add(mapping map[string]*[]*int) {
    sliceptr := &[]*int{}
    mapping["foo"] = sliceptr
    ele := mapping["foo"]

    a := 2

    // won't address of `a` go out of scope?
    ele2 := append(*ele, &a)

    mapping["foo"] = &ele2
}

func main() {       
    mapping := map[string]*[]*int{}    
    add(mapping)        
    fmt.Println(*(*mapping["foo"])[0])
}
jeffreyveon
  • 13,400
  • 18
  • 79
  • 129
  • 1
    As [Mark answered](https://stackoverflow.com/a/59807484/1256452), Go as a language uses escape analysis. You can just think of it as being "smart" though: since Go is a garbage collected language, *all* allocations are via `new` with `delete` just being automatic, and then the compiler is smart and turns some of them into local stack variables when the compiler can prove to itself that this is OK. – torek Jan 19 '20 at 06:07
  • Does this answer your question? [Return pointer to local struct](https://stackoverflow.com/questions/13715237/return-pointer-to-local-struct) – Peter Jan 19 '20 at 09:25

1 Answers1

3

It's safe to reference a after the function declaring it ends, because go does escape analysis. If the compiler can prove it can be accessed safely, it puts it on the stack, if not, it allocates it on the heap.

Build flags can give some insight into the escape analysis:

go build -gcflags "-m" main.go

...
./main.go:10:2: moved to heap: a
...

This might be helpful: Allocation efficiency.

Also, it's less common to see pointers to slices, since a slice is small: a pointer, length and capacity. See slice internals.

Mark
  • 6,731
  • 1
  • 40
  • 38
  • 1
    I came across some gotchas in using slices without pointers (if they are to be mutated): https://www.calhoun.io/why-are-slices-sometimes-altered-when-passed-by-value-in-go/ – jeffreyveon Jan 19 '20 at 11:07