当我有一个双倍的时候,为什么我的结构会出现意想不到的大小?

sdo*_*ble 5 c# double struct

public struct TestStruct
{
    public int first;
    public int second;
    public int third;
}
Run Code Online (Sandbox Code Playgroud)

Marshal.SizeOf返回12,这是我假设的,因为整数是4个字节.如果我要将第三个改为double而不是int,我会期望Marshal.SizeOf返回16.确实如此.但是如果我要添加一个双倍的第四个,Marshal.SizeOf返回24,当我期望20.我可以有10个整数并且最终每个int计为每个4字节.但是如果我在3个整数后添加一个双,那么大小不是我所期望的.

public struct TestStruct //SizeOf 12
{
    public int first;
    public int second;
    public int third;
}  

public struct TestStruct //SizeOf 16
{
    public int first;
    public int second;
    public double third;
}  

public struct TestStruct //SizeOf 24, but I feel like it should be 20
{
    public int first;
    public int second;
    public double third;
    public int fourth;
}
Run Code Online (Sandbox Code Playgroud)

我的想法在哪里让我误入歧途?

Sim*_*ead 8

除了JimR的答案,您还可以使用StructLayout属性显式更改此行为:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TestStruct // sizeof is now 20
{
    public int first;
    public int second;
    public double third;
    public int fourth;
}
Run Code Online (Sandbox Code Playgroud)

您告诉编译器这个结构是按顺序排列的,并且打包类型应该是1,这意味着所有字段都是直接相继布局的.Pack 0(默认值)告诉编译器使用当前平台填充...而其他任何东西(以2的倍数表示)将在那些特定边界中进行布局.我会建议不要这样做......根据你的使用情况,它可能变得无法预测.

有关详细信息,请参阅此MSDN文章:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.pack.aspx


Jim*_*imR 5

你没有考虑在结构中放置任何填充.

在某些情况下,CPU更有效地读取多个大小的内容.例如,一些像int这样的CPU在4字节边界上对齐.如果int未对齐,则某些CPU必须发出2次读取.

当英特尔处理器上的SSE类型指令触及时,int,float和double对对齐特别敏感.