Skip to content

Commit a47764b

Browse files
committed
Add example (function returns of local variable is safe)
1 parent 69e94d1 commit a47764b

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

examples/basic/variables/examples.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package variables
22

33
import (
4+
"github.com/devlights/try-golang/examples/basic/variables/function_returns_address_of_local_variable"
45
"github.com/devlights/try-golang/examples/basic/variables/loopiterator"
56
"github.com/devlights/try-golang/examples/basic/variables/packagescope"
67
"github.com/devlights/try-golang/examples/basic/variables/shadowing"
@@ -25,5 +26,5 @@ func (r *register) Regist(m mappings.ExampleMapping) {
2526
m["short_assignment_statement"] = shortassignment.Basic
2627
m["shadowing_variable"] = shadowing.Basic
2728
m["using_ref_to_loop_iterator_variable"] = loopiterator.CommonMistakePattern
28-
m["passing_loop_variable_to_goroutine_by_pointer"] = loopiterator.PassingLoopVariableToGoroutineByPointer
29+
m["function_returns_address_of_local_variable"] = function_returns_address_of_local_variable.FunctionReturnsAddressOfLocalVariable
2930
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package function_returns_address_of_local_variable
2+
3+
import (
4+
"github.com/devlights/gomy/output"
5+
)
6+
7+
// FunctionReturnsAddressOfLocalVariable -- Goでは関数がローカル変数のアドレスを返すのは全く問題ないことを示すサンプルです.
8+
func FunctionReturnsAddressOfLocalVariable() error {
9+
// -----------------------------------------------
10+
// Go では、関数がローカル変数のアドレスを返すのは全く問題ない.
11+
// (書籍「プログラミング言語 Go」初版 P.35より)
12+
//
13+
// C では、関数のローカル変数は関数からリターンした時点でメモリから開放されてしまうので
14+
// 呼び出し元が戻り値として受け取ったアドレスに大してデリファレンスすると
15+
// 高確率で segmentation fault する.
16+
//
17+
// Go はGCを備えているので、気にせず関数から生成したオブジェクトのポインタを
18+
// 返しても、何の問題もない。
19+
// -----------------------------------------------
20+
i1 := f()
21+
output.Stdoutf("[i1]", "%p\t%v\n", i1, *i1)
22+
23+
i2 := f()
24+
output.Stdoutf("[i2]", "%p\t%v\n", i2, *i2)
25+
26+
// i1, i2 ともに関数fの内部でローカル変数として生成されたものであるが、ちゃんと存在している
27+
// C 言語の場合は、呼び出し元に返ってきた時点でアドレスが示す先のメモリ領域は開放されているため
28+
// 値は不定となる。
29+
30+
f2(i1, i2)
31+
output.Stdoutf("[i1/i2]", "%v\t%v\n", *i1, *i2)
32+
33+
return nil
34+
}
35+
36+
func f() *int {
37+
i := 1
38+
return &i
39+
}
40+
41+
func f2(i1, i2 *int) {
42+
*i1++
43+
*i2++
44+
}

0 commit comments

Comments
 (0)