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?