猿问

存储指向堆栈值的指针(Golang)

我正在尝试在 Go 中进行实验,看看如果我在堆栈上存储一个指向变量的指针,然后在原始变量离开作用域后访问该变量会发生什么。


package main


import "fmt"


var p chan bool;


// a temp struct

type v struct {

    a int

}


func another_thread(vx *v) {

    // this code should be executed after a() returns so vx should be a pointer to a value that's no longer on the stack

    fmt.Printf("another_thread(): %p\n", vx);

    vx.a = 4 // am I updating a dangling pointer that may have unintentional side effects??

    fmt.Println(" - ", vx.a);

    p<-true;

}


func update_v(vx *v) {

    vx.a = 3;


    fmt.Printf("update_v(): %p\n", vx);


    go another_thread(vx)

}


func alloc_on_stack() {

    // allocate v1 on the stack

    var v1 v

    v1.a = 1


    fmt.Printf("alloc_on_stack(): %p\n", &v1);


    // pass a pointer to v1 on the stack

    update_v(&v1)


    // print '3' to prove byref actually took it by reference

    fmt.Println(" - ", v1.a);


    // when the function returns, v1 should be popped off the stack

}


func main() {

    p = make(chan bool)

    alloc_on_stack();

    fmt.Println("outside of alloc_on_stack, waiting");

    <-p;

    fmt.Println("done");

}

在 alloc_on_stack 中,v1 作为局部变量存储在堆栈上。我将指向 v1 的指针传递给 update_v,后者将其传递给 another_thread。由 another_thread 直到 alloc_on_stack 完成后才执行。


然而,当我运行该代码时,我没有收到任何错误,而是看到了以下内容:


alloc_on_stack(): 0x1043617c

update_v(): 0x1043617c

 -  3

outside of alloc_on_stack, waiting

another_thread(): 0x1043617c

 -  4

done

another_thread 中的 vx 不应该是一个悬空指针吗?


慕尼黑5688855
浏览 144回答 2
2回答

小怪兽爱吃肉

不。Go 编译器检测到您正在获取局部变量的地址,并保留它,直到对它的所有引用都消失了。从那时起,该变量可以被垃圾收集。这就是为什么这样的东西不仅被允许,甚至是惯用的:func foo() *Bar {&nbsp; return &Bar{42, "frob"}}
随时随地看视频慕课网APP

相关分类

Go
我要回答