https://inasa.dev/blog/rss.xml

Go | 0尺寸结构体

2023-08-07

下面四个结构体的尺寸大小各是多少?

type A struct {
	x int64
	y int64
}
type A1 struct {
	x int64
	y int64
	z struct{}
}
type A2 struct {
	z struct{}
	x int64
	y int64
}
type A3 struct {
	x int64
	z struct{}
	y int64
}

答案

A: 16
A1: 24
A2: 16
A3: 16

为什么A1的结构体会不同呢?

  • 一个可寻址的结构值的所有字段都可以被取地址,A1可以被取地址,则z也可以被取地址
  • 如果非零尺寸的结构体值的最后一个字段的尺寸是零,那么取此最后一个字段的地址将会返回一个越出了结构体值分配的内存块的地址(可能指向另一个被分配的内存块)
  • 标准的Go编译器会确保取一个非零尺寸的结构体值的最后一个字段的地址时,绝对不会返回越出分配给此结构体值的内存块的地址
  • Go标准编译器通过在需要时在结构体最后的零尺寸字段之后填充一些字节来实现这一点
    • 具体补多少,需要达到内存对齐即可
  • 如果一个结构体的全部字段的类型都是零尺寸的(因此整个结构体也是零尺寸的),那么就不需要再填充字节,因为标准编译器会专门处理零尺寸的内存块

  • Golang101