局部变量的返回地址生成意外值
本篇文章向大家介绍《局部变量的返回地址生成意外值》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。
问题内容我写了下面的代码。我知道返回一个变量的地址 在函数中创建是一种错误的方法,因为创建的局部变量将位于堆栈中,并且 完成函数后,变量将从堆栈中弹出。 我创建了一个名为“latif”的人。然后我使用了changename()函数。它将 person 结构的名称字段更改为“uluman”。它返回了局部变量的地址。函数完成后,局部变量应该被弹出。然后我调用了 sum() 函数来保证堆栈将发生变化(sum 函数的参数将被推送。换句话说,内存中的单元格值 x 点应该发生变化)。所以 x 指向堆栈中的某个位置。
package main
import "fmt"
type Person struct{
name string
age int
}
func sum(a, b int)int{
return a+b
}
func (t Person ) changeName(value string)*Person{
t.name = value
return &t //Delibiratly the address of the local variable is returned
}
func main(){
t := Person{name : "latif" }
fmt.Println("Before" , t.name)
x := t.changeName("uluman")
_= sum(5,10)
fmt.Println("After" , x.name)
return
}
我预计 fmt.println(x.name) 应该打印与 'uluman' 不同的内容,因为 x 指向堆栈地址并且它已更改,但是它打印了“uluman”。 这里出了什么问题?
解决方案
这被称为“逃逸分析”。
go 编译器尝试找出变量的地址是否“转义”函数,如果是,它会在堆而不是堆栈中分配该变量。在这种情况下,它发现t
的地址逃逸了changename
函数,因此它被分配在堆中,而不是在堆栈中。这就是您的程序运行的原因。
例如,这是构造结构的常见方法:
type x struct {
...
}
func newx() *x {
a:=x{}
...
return &a
}
此处,a
分配在堆中,而不是堆栈中,因为编译器知道 a
会转义该函数。
以下内容也有效:
func f() {
i:=0
go func() {
...
i++
...
}()
}
上面,i
转义了 f
,因为 i
的地址位于新创建的 goroutine 的闭包中。 f
返回后,i
继续存活。
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持编程网!更多关于Golang的相关知识,也可关注编程网公众号。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341