使用descoped变量的内存地址是否安全?

时间:2015-01-22 16:09:39

标签: go

这段代码安全吗? b if 块结束时进行描述,但 a 仍然指向 b 的内存地址。在这个简单的例子中它似乎工作(它打印正确的值),但它在语言规范中,这总是有效吗?

使用-m进行编译以检查编译器优化,它说 b 不会转义到堆。

游乐场:http://play.golang.org/p/ZzYkMg6FqB

package main

import "fmt"

func main() {
    a := new(int)
    *a = 10
    if *a > 0 {
        b := 5
        a = &b
    }
    fmt.Println(*a)
}

3 个答案:

答案 0 :(得分:2)

Go中没有悬空指针。

b是否超出范围无关紧要; a现在拥有该地址,并将由GC进行扫描。

答案 1 :(得分:2)

代码是安全的。 Go中的任何赋值都具有复制语义,所以

a = &b

相当于

c = &b
a = c

指派您参考,您可以有效地获取此参考的副本

所以这肯定也会起作用

b := 5
c := &b
a = c
c = nil

fmt.Println(*a)

http://play.golang.org/p/fGTYhEXl1S

答案 2 :(得分:1)

是的,完全没问题。

范围与Go在C或Rust中无关紧要。 Go是一种垃圾收集语言。只要可以访问内存,就不会释放它。在您的示例中,a的原始值将在下一个GC期间释放,因为它不再可用。

编辑:在堆叠上。在您的程序中,b不会逃脱,因为它不需要。如果您重写程序以便在堆栈中分配b时将被删除(例如,like this),您将看到b确实已逃脱。 Go的逃逸分析很聪明,可以看到这样的事情。