Stack vs heap allocation

I am new to go and am coming from C/C++ background. I am having trouble understanding if variables are allocated on stack or heap.

func main() {
	var i1 = 10
	var i2 *int = new(int)

	fmt.Println(&i1, i2)
}

In the above code, i1 should be allocated on stack and i2 on the heap. However, running the above code yields this -

0xc0000a0000 0xc0000a0008

This proves that i1 and i2 are close to each other in memory (specifically 8 bytes apart). i2 has to be allocated on heap, which mean i1 also is allocated on heap. Why isn’t i1 put on stack?

For starters, you could check the outcome of running it with go build -gcflags '-m to check the escape analysis, but if I recall correctly anything passed to the print functions, such as Println, will escape to the heap as calling a function or method on interface types (which is the type those functions accept) must be dynamically dispatched and thus escape. From your example I’d say neither i1 or i2 should escape (see 1) were they not used as arguments, but the things is that the spec doesn’t really state when a variable escapes or not.

That said, I know they’ve been working on escape analysis and this could be outdated, so don’t cite me on this and I’d love someone correcting me here.

1 - To clarify, I mean what I wrote depending on the language and the philosophy of memory allocation. In Go, new() was guaranteed to escape at some point as there was only one implementation and there it escaped, but most of these things are really implementation specific.

1 Like

Take a look over this resources:

https://golang.org/doc/faq#stack_or_heap
https://dougrichardson.org/2016/01/23/go-memory-allocations.html

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.