我最近遇到http://golang-sizeof.tips/,它解释了如何为结构分配内存。我知道,为确保连续的内存分配,我们在为没有填充的变量分配内存时会添加填充。因此,我在我的64位计算机上测试了各种组合,结果发现该站点和我的计算机上的结果不匹配。就是这种情况:
type S2 struct {
a string
b bool
e bool
d int32
f bool
c string
}
主要,下面的代码为我提供48
作为变量的大小。
y := S2{"q", true, true,2,true,"w"}
fmt.Println(unsafe.Sizeof(y))
但这与http://golang-sizeof.tips/?t=blahblah的假设有所不同。为什么会观察到这种行为? (我希望这不是我的计算机本身就有问题)。
编辑:从逻辑上讲,填充d
和f
之间的填充是不必要的
为了确定,我还运行了以下代码。
fmt.Println(unsafe.Offsetof(y.a))
fmt.Println(unsafe.Offsetof(y.b))
fmt.Println(unsafe.Offsetof(y.e))
fmt.Println(unsafe.Offsetof(y.d))
fmt.Println(unsafe.Offsetof(y.f))
fmt.Println(unsafe.Offsetof(y.c))
结果:
0
16
17
20
24
32
play.golang.org使用32位计算机,因此我怀疑是否可以在其中复制相同的内容!
答案 0 :(得分:1)
您对48个字节的计算对于amd64是正确的。
package main
import (
"fmt"
"unsafe"
)
type S2 struct { // align 16
a string // size 16 = 8 + 8
b bool // size 1
e bool // size 1
// pad size 2
d int32 // size 4
f bool // size 1
// pad size 7
c string // size 16 = 8 + 8
}
func main() {
y := S2{}
fmt.Println(unsafe.Sizeof(y))
fmt.Println(unsafe.Offsetof(y.a))
fmt.Println(unsafe.Offsetof(y.b))
fmt.Println(unsafe.Offsetof(y.e))
fmt.Println(unsafe.Offsetof(y.d))
fmt.Println(unsafe.Offsetof(y.f))
fmt.Println(unsafe.Offsetof(y.c))
fmt.Println(&y.a)
fmt.Println(&y.b)
fmt.Println(&y.e)
fmt.Println(&y.d)
fmt.Println(&y.f)
fmt.Println(&y.c)
}
输出:
48
0
16
17
20
24
32
0xc000070150
0xc000070160
0xc000070161
0xc000070164
0xc000070168
0xc000070170
Read words separated by space & string value also contains space in a batch script