为什么这两个结构在内存中具有不同的大小?

dfek:

假设我有以下两个结构:

package main

import (
    "fmt"
    "unsafe"
)

type A struct {
    int8
    int16
    bool
}

type B struct {
    int8
    bool
    int16
}

func main() {
    fmt.Println(unsafe.Sizeof(A{}), unsafe.Sizeof(B{})) // 6 4
}

的大小A为6个字节。但是,大小B为4个字节。
我以为它与它们在内存中的布局有关,但是我不确定我为什么理解它的行为。
编译器无法检测和优化吗?(重新排列字段顺序)

链接到代码

peterSO:

由于对齐导致填充。

Go编程语言规范

尺寸和对齐保证

对于数字类型,保证以下大小:

type                                 size in bytes

byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16

保证以下最小对齐方式属性:

  • 对于任何类型的变量x:unsafe.Alignof(x)至少为1。

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

  • 对于数组类型的变量x:unsafe.Alignof(x)与数组元素类型的变量的对齐方式相同。

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


例如,

package main

import (
    "fmt"
    "unsafe"
)

type A struct {
    x int8
    y int16
    z bool
}

type B struct {
    x int8
    y bool
    z int16
}

func main() {
    var a A
    fmt.Println("A:")
    fmt.Println("Size:   ", unsafe.Sizeof(a))
    fmt.Printf("Address: %p %p %p\n", &a.x, &a.y, &a.z)
    fmt.Printf("Offset:  %d %d %d\n", unsafe.Offsetof(a.x), unsafe.Offsetof(a.y), unsafe.Offsetof(a.z))
    fmt.Println()
    var b B
    fmt.Println("B:")
    fmt.Println("Size:   ", unsafe.Sizeof(b))
    fmt.Printf("Address: %p %p %p\n", &b.x, &b.y, &b.z)
    fmt.Printf("Offset:  %d %d %d\n", unsafe.Offsetof(b.x), unsafe.Offsetof(b.y), unsafe.Offsetof(b.z))
}

游乐场:https//play.golang.org/p/_8yDMungDg0

输出:

A:
Size:    6
Address: 0x10410020 0x10410022 0x10410024
Offset:  0 2 4

B:
Size:    4
Address: 0x10410040 0x10410041 0x10410042
Offset:  0 1 2

您可能正在匹配外部struct语言,也许是另一种语言。由您决定告诉编译器您想要什么。编译器不会猜测。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Python

为什么两个相同的列表具有不同的内存占用量?

来自分类Dev

为什么这两个float64具有不同的值?

来自分类Dev

为什么这两个结构不相等?

来自分类Dev

JavaScript日期:为什么这两个日期不同?

来自分类Dev

为什么这两个日期时间不同?

来自分类Dev

为什么这两个右值引用示例具有不同的行为?

来自分类Dev

为什么这两个对addEventListener的javascript调用会有不同的结果

来自分类Dev

为什么这两个功能的签名不同?

来自分类Dev

为什么这两个函数的类型不同?

来自分类Dev

为什么这两个序言句子的输出不同?

来自分类Dev

为什么这两个查询产生不同的结果?

来自分类Dev

为什么两个具有相同文本和编码但大小不同的文件?

来自分类Dev

为什么这两个带有“ EXISTS”的查询的行为不同?

来自分类Dev

为什么这两个代码片段具有相同的效果?

来自分类Dev

为什么这两个DOMDocument函数的行为不同?

来自分类Dev

为什么Java和Lisp中的这两个等效表达式会有不同的结果?

来自分类Dev

为什么这两个FParsec片段不同?

来自分类Dev

为什么这两个警报显示不同的值?

来自分类Dev

为什么这两个“ cat”命令的结果不同?

来自分类Dev

为什么这两个代码给出不同的输出

来自分类Dev

xUnit.net:为什么这两个等效测试会有不同的结果?

来自分类Dev

为什么两个不同查询的结果在phpMyadmin中具有不同的UI?

来自分类Dev

为什么这两个 DateTime 实例不同?

来自分类Dev

为什么这两个整型变量和两个双精度变量(貌似)在内存中共享同一个地址?

来自分类Dev

为什么这两个模板函数的输出不同?

来自分类Dev

为什么输出与这两个不同?

来自分类Dev

为什么这两个函数的结果不同?

来自分类Dev

这两个结果有什么不同?

来自分类Dev

为什么这两个循环返回不同的结果?

Related 相关文章

  1. 1

    为什么两个相同的列表具有不同的内存占用量?

  2. 2

    为什么这两个float64具有不同的值?

  3. 3

    为什么这两个结构不相等?

  4. 4

    JavaScript日期:为什么这两个日期不同?

  5. 5

    为什么这两个日期时间不同?

  6. 6

    为什么这两个右值引用示例具有不同的行为?

  7. 7

    为什么这两个对addEventListener的javascript调用会有不同的结果

  8. 8

    为什么这两个功能的签名不同?

  9. 9

    为什么这两个函数的类型不同?

  10. 10

    为什么这两个序言句子的输出不同?

  11. 11

    为什么这两个查询产生不同的结果?

  12. 12

    为什么两个具有相同文本和编码但大小不同的文件?

  13. 13

    为什么这两个带有“ EXISTS”的查询的行为不同?

  14. 14

    为什么这两个代码片段具有相同的效果?

  15. 15

    为什么这两个DOMDocument函数的行为不同?

  16. 16

    为什么Java和Lisp中的这两个等效表达式会有不同的结果?

  17. 17

    为什么这两个FParsec片段不同?

  18. 18

    为什么这两个警报显示不同的值?

  19. 19

    为什么这两个“ cat”命令的结果不同?

  20. 20

    为什么这两个代码给出不同的输出

  21. 21

    xUnit.net:为什么这两个等效测试会有不同的结果?

  22. 22

    为什么两个不同查询的结果在phpMyadmin中具有不同的UI?

  23. 23

    为什么这两个 DateTime 实例不同?

  24. 24

    为什么这两个整型变量和两个双精度变量(貌似)在内存中共享同一个地址?

  25. 25

    为什么这两个模板函数的输出不同?

  26. 26

    为什么输出与这两个不同?

  27. 27

    为什么这两个函数的结果不同?

  28. 28

    这两个结果有什么不同?

  29. 29

    为什么这两个循环返回不同的结果?

热门标签

归档