GO中什么情况会使用变量逃逸.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

GO中什么情况会使用变量逃逸

目录C程序GO程序GO的逃逸是啥样子的?你知道GO中什么情况会变量逃逸吗?首先我们先来看看什么是变量逃逸

Go语言将这个以前我们写C/C++时候需要做的内存规划和分配,全部整合到了GO的编译器中,GO中将这个称为变量逃逸

GO通过编译器分析代码的特征和代码的生命周期,决定应该使用堆还是栈来进行内存分配

C代码和GO代码对比哪个会崩溃?

咱们写一个简单的例子,在C里面内存分配到栈上面还是堆上面是一个很明确的事情

例如

函数中的变量是分配在栈上面,会随着该函数调用完毕后随之销毁掉

程序员自己malloc开辟的内存是在堆上面,需要程序员自己去释放

那么问题来了:

如果我们将某一个函数中的局部变量的地址(全篇以局部变量为例),作为该函数的返回值,最终在函数外部去访问这个局部变量的地址,是否会出错呢?一起来看看吧

C程序

test.c

int*get_res(intnum){

inttmp=num+10;

returntmp;

intmain(){

int*res=get_res(80);

printf(%d--%p\n,*res,res);

上面写了一个简单的C代码,获取传入数据并+10得到的结果

#gcctest.c-otest

test.c:Infunction‘get_res:

test.c:7:12:warning:functionreturnsaddressoflocalvariable[-Wreturn-local-addr]

returntmp;

^~~~

#./test

Segmentationfault

这里可以看出编译程序,报了warning了,不过不影响程序的编译,这个warning报错信息是因为我们返回了临时变量的地址,C编译器检测到了,给我们抛出了一个warning

执行编译的程序后,崩溃了,熟悉C的小伙伴一点都不惊慌,他们不会写出这种代码

出现段错误的原因很明显,上面有说到,是因为外部访问了局部变量的地址,外部访问的时候,此时这个局部变量已经被销毁了,此时外部访问的这个指针,属于野指针,因此出现程序崩溃

GO程序

go程序的逻辑和上面C程序的逻辑一模一样,那么我们看看是否会出现程序崩溃呢

funcgetRes(numint)*int{

tmp:=num+10

returntmp

funcmain(){

res:=getRes(80)

fmt.Printf(%d--%p\n,*res,res)

执行上述代码,查看效果

#gorunmain.go

90--0xc420018078

熟悉go语言的小伙伴看到这里心中也毫无波澜,程序正常执行,没有崩溃,因为他们知道原因,这个现象属于变量逃逸

那么我们一起来看看GO为什么会这样做,是如何做的呢?

GO的逃逸是啥样子的?

上面有说到GO不会像C/C++一样需要程序员自己去关心内存分配,是期望GO程序员更多的关注逻辑

因此内存分配这一块,GO编译器都做的妥妥的,一个变量是分配在栈上面还是堆上面,不是简单的看一个变量是局部变量就分配到栈上,这个是根据具体的使用的,有时候它也会被分配到堆上面

当我们发现本应该分配在栈上面的变量,却分配在堆上面了,说明发生了逃逸

开始探究和验证

我们可以尝试写一个简单的demo,还是将局部变量的地址返回到外部去,外部来访问这个局部变量的地址

funcgetRes(tmpint)*int{

vart1int=1

vart2int=2

vart3int=3

println(tmp,t1,t2,t3)

returnt2

funcmain(){

res:=getRes(80)

println(*res,res)

执行上述代码查看效果

0xc420045f500xc420045f680xc420045f600xc420045f58

20xc420045f60

通过上面的将变量地址打印出来貌似没有看出上面端倪,地址是也是连续的

那么我们使用go提供的工

文档评论(0)

157****2177 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档