dongpiao0731 2018-05-05 17:56
浏览 194

进入内存中的分片地址

I ran the following code on 64-bits OS and got the result that the difference between each slice's address is 32Byte(0xc42008a060 - 0xc42008a040 0xc42008a040 - 0xc42008a020). I guess it should be 24Byte, because the size of slice is 24B and the align is 8. Just like the example of int64.

package main

import (
    "fmt"
    "unsafe"
)
func main() {
    var sl1 []int
    var sl2 []int
    var sl3 []int
    fmt.Printf("slice:
")
    fmt.Printf("sl1 addr %p, align %d, size %d
", &sl1, unsafe.Alignof(sl1), unsafe.Sizeof(sl1))
    fmt.Printf("sl1 addr %p, align %d, size %d
", &sl2, unsafe.Alignof(sl2), unsafe.Sizeof(sl2))
    fmt.Printf("sl1 addr %p, align %d, size %d
", &sl3, unsafe.Alignof(sl3), unsafe.Sizeof(sl3))

    var i1 int
    var i2 int
    var i3 int
    fmt.Printf("int:
")
    fmt.Printf("i1 addr %p, align %d, size %d
", &i1, unsafe.Alignof(i1), unsafe.Sizeof(i1))
    fmt.Printf("i2 addr %p, align %d, size %d
", &i2, unsafe.Alignof(i2), unsafe.Sizeof(i2))
    fmt.Printf("i3 addr %p, align %d, size %d
", &i3, unsafe.Alignof(i3), unsafe.Sizeof(i3))
}

output:

slice:
slice:
sl1 addr 0xc42008a020, align 8, size 24
sl1 addr 0xc42008a040, align 8, size 24
sl1 addr 0xc42008a060, align 8, size 24
int:
i1 addr 0xc42007c020, align 8, size 8
i2 addr 0xc42007c028, align 8, size 8
i3 addr 0xc42007c030, align 8, size 8

At first I guess there might be something else occupied the extra 8B, and then I rerun it many time and the addresses are changed sometime when I modify a few codes, but I always found the difference was 32B or bigger. I just know a little about slice and struct padding and very confused about it. Can anyone help me. Many thanks

-------update another test-----

I print the value via point just like

package main

import (
    "fmt"
    "unsafe"
)

func main() {

    arr := [5]int{1, 2, 3, 4, 5}
    s1 := arr[0:1]
    s2 := arr[0:2]

    fmt.Printf("arr addr %p
", &arr)
    fmt.Printf("s1 addr %p, align %d, size %d
", &s1, unsafe.Alignof(s1), unsafe.Sizeof(s1))
    fmt.Printf("s2 addr %p, align %d, size %d
", &s2, unsafe.Alignof(s2), unsafe.Sizeof(s2))

    //var spInt *int64 = (*int64)(unsafe.Pointer(sp))
    fmt.Printf("
s1:
")
    sp := &s1
    fmt.Printf("address: %v
",     unsafe.Pointer(uintptr(unsafe.Pointer(sp))))
    fmt.Println(fmt.Sprintf("+ 0(arr): 0x%x", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp))))))
    fmt.Printf("+ 8(len): %d
", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp)) + uintptr(8))))
    fmt.Printf("+16(cap): %d
", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp)) + uintptr(16))))
    fmt.Printf("+24(unknow): %d
", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp)) + uintptr(24))))

    fmt.Printf("
s2:
")
    sp = &s2
    fmt.Printf("address: %v
", unsafe.Pointer(uintptr(unsafe.Pointer(sp))))
    fmt.Println(fmt.Sprintf("+ 0(arr): 0x%x", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp))))))
    fmt.Printf("+ 8(len): %d
", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp)) + uintptr(8))))
    fmt.Printf("+16(cap): %d
", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp)) + uintptr(16))))
    fmt.Printf("+24(unknow): %d

", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(sp)) + uintptr(24))))
}

and I get the result:

arr addr 0xc420018150
s1 addr 0xc42000a060, align 8, size 24
s2 addr 0xc42000a080, align 8, size 24

s1:
address: 0xc42000a060
+ 0(arr): 0xc420018150
+ 8(len): 1
+16(cap): 5
+24(unknow): 0

s2:
address: 0xc42000a080
+ 0(arr): 0xc420018150
+ 8(len): 2
+16(cap): 5
+24(unknow): 0

The first 8B is the address of data array, the second is the length of slice and the third is capacity of slice. But the last 8B seems to be empty. What the last 8B is used for? For padding?

  • 写回答

1条回答 默认 最新

  • doure8758 2018-05-06 01:08
    关注

    You can validate your assumptions with the project tyranron/golang-sizeof.tips and its online page golang-sizeof.tips

    Example

    The size is as expected.
    But the atomic package does mention:

    The first word in a variable or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned.

    See this thread:

    The quote is "The first word in a global variable or in an allocated struct or slice can be relied upon to be 64-bit aligned."
    The key phrase there is "allocated", not "struct or slice."

    The first word in a struct or slice that is allocated via new or via a composite literal will be 64-bit aligned.
    A struct inside a slice or array is not allocated by itself, and no particular alignment is guaranteed beyond that of unsafe.AlignOf.

    评论

报告相同问题?

悬赏问题

  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录