亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

Go中數組的內存布局?

Go中數組的內存布局?

Go
qq_遁去的一_1 2023-01-03 09:52:54
我的代碼如下。當我檢查值的地址時,它存儲為280 288 290 298. 為什么以這種模式存儲?package main    import "fmt"func main() {    const a = 1111111111111111111    test := [7]int{a, 1, 33333,4,6,7,7}    fmt.Println(&test[0])    fmt.Println(&test[1])    fmt.Println(&test[2])    fmt.Println(&test[3])    fmt.Println(&test[4])    fmt.Println(&test[5])    fmt.Println(&test[6])}輸出 :0xc00000e2800xc00000e2880xc00000e2900xc00000e2980xc00000e2a00xc00000e2a80xc00000e2b0
查看完整描述

1 回答

?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

毫不奇怪,Go 數組在內存中是連續布局的。然后由于 Go 類型是靜態大小的,第 n 個項目的地址等于第 0 個元素的地址加上等于項目類型大小的字節偏移量。

這可以大致形式化為(偽代碼):

addr_n = addr_0 + (n * size_of(item))

在 Go 代碼中,使用unsafe.Add(自 Go 1.17 起):

func main() {

    const a = 1111111111111111111

    x := [7]int{a, 1, 33333, 4, 6, 7, 7}


    unsafePointer := unsafe.Pointer(&x[0])

    for i := range x {

        step := unsafe.Sizeof(int(0))

        addr_n := unsafe.Add(unsafePointer, int(step)*i)

        fmt.Printf("addr: %p, val: %d\n", addr_n, *(*int)(addr_n))

    }

}

哪個打?。?/p>


addr: 0xc000102000, val: 1111111111111111111

addr: 0xc000102008, val: 1

addr: 0xc000102010, val: 33333

addr: 0xc000102018, val: 4

addr: 0xc000102020, val: 6

addr: 0xc000102028, val: 7

addr: 0xc000102030, val: 7

如果還不是很清楚,十六進制數就是內存地址。這就是fmt包通常格式化指針的方式。

但是請注意,int特別是的大小取決于平臺,因此在上面的代碼片段中您不能只添加8. 要使其具有確定性,您可以使用unsafe.Sizeof(int(0)).

游樂場:https ://go.dev/play/p/4hu8efVed96


查看完整回答
反對 回復 2023-01-03
  • 1 回答
  • 0 關注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號