Go函数返回局部变量指针结果不符预期:与C栈行为差异原因咨询
First, let's look at your code for reference:
import "fmt" func getIntPointer(i int) *int { var result int result = i + 1 return &result } func main () { ip1 := getIntPointer(4) ip2 := getIntPointer(10) fmt.Println(*ip1, *ip2) fmt.Printf("%p %p\n", ip1, ip2) }
Expectation vs. Actual Output
Your Expected Output:
11 11
address1 address1Actual Output:
5 11
address1 address2
Why the Difference? Go's Escape Analysis
Your intuition comes straight from C's stack behavior, which makes total sense—C reuses stack space once a function exits. But Go has a key mechanism called escape analysis that changes everything here. Here's what's going on:
- When Go's compiler encounters code that returns the address of a local variable (like
&result), it runs escape analysis to figure out if the variable needs to live beyond the function's stack frame. - Since you're returning the pointer to the caller, the compiler decides
resultcan't stay on the stack (it would become invalid as soon as the function exits). Instead, it allocatesresulton the heap for each individual function call. - That's why each call to
getIntPointergets a unique heap allocation: hence the different memory addresses. And since each allocation holds the correct computed value (4+1=5 for the first call, 10+1=11 for the second), you see those values instead of the reused stack value you expected from C.
Just to clarify: Go does reuse stack space for variables that don't escape the function (i.e., their addresses never leave the function's scope). But in your code, result clearly escapes to the caller, so heap allocation is mandatory.
Key Takeaway
Go avoids the dangling pointer issues common in C by automatically promoting variables to the heap when their addresses are returned to callers. This escape analysis-driven behavior ensures memory safety, which is why your output doesn't match the C-style stack reuse you expected.
内容的提问来源于stack exchange,提问作者Andy Straw

