第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

局部變量的返回地址生成意外值

局部變量的返回地址生成意外值

Go
繁星coding 2023-08-07 11:09:59
我寫了下面的代碼。我知道返回在函數(shù)中創(chuàng)建的變量的地址是錯誤的方法,因為創(chuàng)建的局部變量將位于堆棧中,并且在完成函數(shù)后該變量將從堆棧中彈出。我創(chuàng)建了一個名為“l(fā)atif”的人。然后我使用了changeName()函數(shù)。它將 person 結(jié)構(gòu)的名稱字段更改為“uluman”。它返回了局部變量的地址。函數(shù)完成后,局部變量應(yīng)該被彈出。然后我調(diào)用了 sum() 函數(shù)來保證堆棧將發(fā)生變化(sum 函數(shù)的參數(shù)將被推送。換句話說,內(nèi)存中的單元格值 x 點應(yīng)該發(fā)生變化)。所以 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    }我預(yù)計fmt.Println(x.name)應(yīng)該打印與“uluman”不同的內(nèi)容,因為 x 指向堆棧地址并且它已經(jīng)更改,但它打印了“uluman”。這里有什么問題嗎?
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA貢獻(xiàn)1818條經(jīng)驗 獲得超3個贊

這被稱為“逃逸分析”。


Go編譯器嘗試找出變量的地址是否“轉(zhuǎn)義”了函數(shù),如果是,它會在堆而不是堆棧中分配該變量。在這種情況下,它發(fā)現(xiàn) 的地址t逃逸了changeName函數(shù),因此它被分配在堆中,而不是堆棧中。這就是你的程序有效的原因。


例如,這是構(gòu)造結(jié)構(gòu)的常見方法:


type X struct {

  ...

}


func NewX() *X {

   a:=X{}

   ...

   return &a

}

這里,a是在堆中分配的,而不是在堆棧上,因為編譯器知道它a會轉(zhuǎn)義函數(shù)。


以下內(nèi)容也有效:


func f() {

  i:=0

  go func() {

    ...

    i++

    ...

   }()

}

上面,i轉(zhuǎn)義了f,因為地址i位于新創(chuàng)建的 goroutine 的閉包中。f回國后繼i續(xù)生活。


查看完整回答
反對 回復(fù) 2023-08-07
  • 1 回答
  • 0 關(guān)注
  • 149 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號