Debugging Sparrow

Golang 지역 변수의 주소 리턴

2018/08/24 go golang escape analysis

발현

Golang으로 프로그래밍을 하던 도중 아래와 같은 프로그램을 소스를 짜게 되었습니다.

Go
1
2
3
4
5
6
7
8
9
10
11

func test() *int {
a := 1
return &a
}

func main() {
var value = test()
print(*value)
}

지역 변수의 주소를 return 해서 참조를 이용해 값을 프린트하는 코드인데요. 출력은 정상적으로 1이 나옵니다.
겉으로 보기엔 문제가 없지만 제 얕은 지식으로는 받아들이기 힘들었습니다. 지역 변수가 함수가 끝났는데도 값이 그대로 살아있습니다.
그냥 메모리에 올라가 있어서 주소로 값이 받아지는 건가 싶어서 call stack을 여러 번 쌓아보기도 했는데도 출력은 그대로.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <stdio.h>

int* func()
{
int a = 1;
return &a;
}

int main()
{
int* b = func();
printf(*b);
}

혹시 제가 잘못 알고 있나 싶어 c로도 짜봤습니다. 결과는 Segmentation fault. 다행이네요.

원인

제가 이상한 게 아라면 언어에 뭔가 비밀이 있겠지요.
effective-go에서는 위와 같은 연산이 허용이 된다고 나와있습니다.

Note that, unlike in C, it’s perfectly OK to return the address of a local variable; the storage associated with the variable survives after the function returns.

Go의 컴파일러에는 escape analysis가 있어 지역 변수의 주소가 함수에서 반환될 때 (분석을 통해 오류가 발생하지 않도록 하기 위해) heap으로 escape 됩니다.
Language Mechanics On Escape Analysis에 자세한 내용이 있습니다.

Author: dbgsprw

Link: https://dbgsprw.github.io/2018/08/24/hello-world/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
API Gateway with Zuul 2.0 (1)
CATALOG
  1. 1. 발현
  2. 2. 원인