英文:
Is it safe to use the memory address of descoped variables?
问题
这段代码安全吗?当 if 块结束时,b 被解除作用域,但 a 仍然指向 b 的内存地址。在这个简单的例子中,它似乎是有效的(打印了正确的值),但这在语言规范中总是有效吗?
使用 -m 编译以检查编译器优化时,它表示 b 没有逃逸到堆上。
Playground: 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)
}
英文:
Is this code safe? b gets descoped when the if block ends, but a still points to b's memory address. In this simple example it seems to work (it prints the right value), but it is in the language specification that this will always work?
Compiling with -m to check the compiler optimizations, it says that b doesn't escape to the heap.
Playground: 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)
}
答案1
得分: 2
在Go语言中不存在悬空指针。
即使b
超出了作用域,也没有关系;a
现在持有该地址,并且会被垃圾回收器扫描到。
英文:
There are no dangling pointers in Go.
It doesn't matter if b
is out of scope; a
now holds that address and would be scanned by the GC.
答案2
得分: 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
英文:
Code is safe. Any assignment in Go has copy semantic, so
a = &b
is equivalent to
c = &b
a = c
assigning to reference you effectively take a copy of this reference
so this sure will also work
b := 5
c := &b
a = c
c = nil
fmt.Println(*a)
答案3
得分: 1
是的,这完全没问题。
在Go语言中,作用域并不像C或Rust那样重要。Go是一种垃圾回收语言。只要内存可以被访问到,它就不会被释放。在你的例子中,变量a
的原始值在下一次垃圾回收时会被释放,因为它不再可访问。
**编辑:**关于栈。在你的程序中,变量b
没有逃逸,因为它不需要逃逸。如果你重写你的程序,使得b
在栈上分配后会被删除(例如,像这样:链接),你会发现b
确实逃逸了。Go的逃逸分析足够聪明,可以看到这样的情况。
英文:
Yes, it's perfectly fine.
Scope doesn't matter in Go as much as in C or Rust. Go is a garbage-collected language. As long as the memory can be reached, it won't be freed. In your example, the original value of a
will be freed during the next GC, as it's not reachable any more.
Edit: On stack. In your program, b
does not escape because it doesn't need to. If you rewrite your program so that b
will be deleted if allocated on stack (for example, like this) you'll see that b
does escape. Go's escape analysis is clever enough to see such things.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论