栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如果字段顺序不同,结构的大小也将不同

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如果字段顺序不同,结构的大小也将不同

1.结构尺寸

TL; DR; (摘要):如果对字段进行重新排序,将使用不同的隐式填充,并且隐式填充计入的大小

struct

注意结果取决于目标体系结构。
适用于您发布结果时

GOARCH=386
,但是当
GOARCH=amd64
,既大小的
A{}
B{}
将是24个字节。

结构的字段地址必须对齐,并且类型的字段地址

int64
必须为8字节的倍数。规格:包装
unsafe

计算机体系结构可能需要 对齐 内存地址; 也就是说,如果变量的地址是一个因子的倍数,则该变量的类型为 alignment
。该函数

Alignof
采用表示任何类型变量的表达式,并以字节为单位返回(变量的类型)对齐方式。

对齐

int64
为8个字节:

fmt.Println(unsafe.Alignof((int64(0)))) // Prints 8

因此,在

A
第一个字段为的情况下,
bool
后面有7个字节的隐式填充,
A.a
因此该
A.b
类型的填充
int64
可以在8的倍数的地址上开始。这保证了(确切地需要7个字节的填充)为在
struct
本身对准这是8的倍数的地址,因为这是所有字段的最大尺寸。请参阅:规格:尺寸对齐保证:

对于

x
结构类型的变量:
unsafe.Alignof(x)
是的
unsafe.Alignof(x.f)
每个字段
f
的所有值中的最大值
x
,但至少是
1

B
(如果
GOARCH=386
是您的情况)情况下,在
B.a
type字段之后将只有3个字节的隐式填充,
bool
因为此字段后面是type字段
int
(其大小为4个字节),而不是
int64

int
如果对齐则为4个字节,如果对齐为
GOARCH=386
8个字节
GOARCH=amd64

fmt.Println(unsafe.Alignof((int(0))))   // Prints 4 if GOARCH=386, and 8 if GOARCH=amd64

使用

unsafe.Offsetof()
找出领域的偏移量:

// output 24a := A{}fmt.Println(unsafe.Sizeof(a),    unsafe.Offsetof(a.a), unsafe.Offsetof(a.b), unsafe.Offsetof(a.c))// output 16b := B{}fmt.Println(unsafe.Sizeof(b),    unsafe.Offsetof(b.b), unsafe.Offsetof(b.a), unsafe.Offsetof(b.c))// output 0fmt.Println(unsafe.Sizeof(C{}))var i intfmt.Println(unsafe.Sizeof(i))

输出if

GOARCH=386
(在Go Playground上尝试):

24 0 8 1616 0 8 1204

如果输出

GOARCH=amd64

24 0 8 1624 0 8 1608

2.零大小值

规格:尺寸对齐保证:

如果结构或数组类型不包含大小大于零的字段(或元素),则其大小为零。 两个不同的零大小变量在内存中可能具有相同的地址。

因此,该规范仅提示使用相同的内存地址,但这不是必需的。但是,当前的实现遵循它。也就是说,不会为大小为零的类型的值分配任何内存,这包括空结构

struct{}
和长度为零的数组,例如
[0]int
,或元素大小为零(且具有任意长度)的数组。

请参阅以下示例:

a := struct{}{}b := struct{}{}c := [0]int{}d := [3]struct{}{}fmt.Printf("%p %p %p %p %p", &a, &b, &c, &d, &d[2])

输出(在Go Playground上尝试):所有地址都相同。

0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c

有关有趣且相关的主题,请阅读: Dave
Cheney:填充很难



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/633176.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号