【问题标题】:sizeof gives a different result depending on field ordersizeof 根据字段顺序给出不同的结果
【发布时间】:2013-06-05 19:27:45
【问题描述】:

我编写了一个小型控制台应用程序来测试sizeof 运算符:

public class Program
{
    public static unsafe void Main(string[] args)
    {
        // Native
        Console.WriteLine("The size of bool is {0}.", sizeof(bool));
        Console.WriteLine("The size of short is {0}.", sizeof(short));
        Console.WriteLine("The size of int is {0}.", sizeof(int));
        Console.WriteLine("The size of long is {0}.", sizeof(long));

        // Custom
        Console.WriteLine("The size of Bool1 is {0}.", sizeof(Bool1));
        Console.WriteLine("The size of Bool2 is {0}.", sizeof(Bool2));
        Console.WriteLine("The size of Bool1Int1Bool1 is {0}.", sizeof(Bool1Int1Bool1));
        Console.WriteLine("The size of Bool2Int1 is {0}.", sizeof(Bool2Int1));
        Console.WriteLine("The size of Bool1Long1 is {0}.", sizeof(Bool1Long1));
        Console.WriteLine("The size of Bool1DateTime1 is {0}.", sizeof(Bool1DateTime1));

        Console.Read();
    }
}

public struct Bool1
{
    private bool b1;
}

public struct Bool2
{
    private bool b1;
    private bool b2;
}

public struct Bool1Int1Bool1
{
    private bool b1;
    private int i1;
    private bool b2;
}

public struct Bool2Int1
{
    private bool b1;
    private bool b2;
    private int i1;
}

public struct Bool1Long1
{
    private bool b1;
    private long l1;
}

public struct Bool1DateTime1
{
    private bool b1;
    private DateTime dt1;
}

给出以下输出:

似乎声明字段的顺序会影响结构的大小

我原以为 Bool1Int1Bool1 返回的大小为 6 (1 + 4 + 1) 但它却给出了 12 (我想是 4 + 4 + 4? ?)!因此,编译器似乎通过将每个字节打包为 4 个字节来对齐成员。

如果我在 32 位或 64 位系统上,它会改变什么吗?

第二个问题,对于long 类型的测试,bool 这次被压缩为 8 个字节。 谁能解释一下?

【问题讨论】:

标签: c# .net structure sizeof


【解决方案1】:

这是因为编译器对齐成员,因此优化了它们的访问速度,而不是它们的内存占用。

你可以添加

[StructLayout(LayoutKind.Sequential, Pack=1)]

在结构定义之前,它应该在 1 个字节的空间中对齐。

【讨论】:

    【解决方案2】:

    这是因为编译器对齐结构的成员变量以允许 CPU 快速读取和写入它们的值。

    在这里,正如您所观察到的,它在每个 bool 之后添加 3 个虚拟字节。

    【讨论】:

    • 为什么没有为 Bool2Int1 对齐它们?
    • @DmitryKhryukin。基本上,它根据变量的大小对齐变量。 bool 是一个字节,所以它们在一个字节边界上对齐,int 是四个字节,所以它们在四个字节边界上对齐。所以对于Bool2Int,'b1' 位于偏移量 0,b2 位于偏移量 1,i1 位于偏移量 4。
    • 与 Bool1Int1Bool1 有什么区别?我在你的回答中没有看到。
    • @DmitryKhryukin。编译器观察到最大的成员变量类型是 int - 4 个字节,因此它尝试将所有内容放在 4 个字节的块中。在 Bool2Int1 中,它可以将 2 个第一个 bool 打包成 4 个字节,在 Bool1Int1Bool1 中,它们由 int 分隔,因此必须将它们对齐。
    猜你喜欢
    • 2017-02-05
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2016-03-17
    • 2023-03-30
    • 2020-01-06
    • 2019-05-22
    • 1970-01-01
    相关资源
    最近更新 更多