Go中数组的内存布局?

我的代码如下。当我检查值的地址时,它存储为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])

}


输出 :


0xc00000e280

0xc00000e288

0xc00000e290

0xc00000e298

0xc00000e2a0

0xc00000e2a8

0xc00000e2b0


qq_遁去的一_1
浏览 108回答 1
1回答

月关宝盒

毫不奇怪,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))    }}哪个打印:addr: 0xc000102000, val: 1111111111111111111addr: 0xc000102008, val: 1addr: 0xc000102010, val: 33333addr: 0xc000102018, val: 4addr: 0xc000102020, val: 6addr: 0xc000102028, val: 7addr: 0xc000102030, val: 7如果还不是很清楚,十六进制数就是内存地址。这就是fmt包通常格式化指针的方式。但是请注意,int特别是的大小取决于平台,因此在上面的代码片段中您不能只添加8. 要使其具有确定性,您可以使用unsafe.Sizeof(int(0)).游乐场:https ://go.dev/play/p/4hu8efVed96
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go