我有几个具有顺序布局的结构:
struct S1
{
Guid id;
}
struct S2
{
Guid id;
short s;
}
struct S3
{
Guid id;
short s;
short t;
}
在上述结构类型上调用 Marshal.SizeOf
,
我得到了:
Size:
S1 = 16, as expected.
S2 = 20, copied an instance to a byte array, it only occupies first 18 bytes.
S3 = 20.
我的问题是,为什么 S2 的大小是 20 而不是 18。只有当 Guid
在结构中时才会出现这个问题。
很抱歉无法从 msdn 中找到任何有用的信息。我知道 Marshal.SizeOf
给出了该类型在内存中占用的空间大小,但我想知道为什么它需要 2 个额外字节才能使大小成为 4 的倍数。
我怎样才能避免这个“问题”?
非常感谢!
最佳答案
这是因为隐含的 [StructLayout] 附加到结构,Pack 字段是重要的字段。它规定了结构成员在编码后如何对齐。 Pack 的默认值为 8。这表示任何小于或等于 8 字节的成员都是对齐的。换句话说,short 将对齐到 2 的倍数的偏移量,int 对齐到 4,long 或 double 对齐到 8。
关键点是在创建结构数组时对齐仍然有效。用一个更简单的例子更容易演示:
using System;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
Console.WriteLine(Marshal.SizeOf(typeof(Example)));
Console.ReadLine();
}
}
struct Example {
public int a;
public short b;
}
输出:8
a
成员强制增加大小,将两个额外的填充字节添加到结构中,以确保在使用结构时 int 仍然与 4 的倍数的偏移量对齐数组。您可以通过应用属性来更改结果:
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct Example {
public int a;
public short b;
}
输出:6
当在数组中使用该结构时,a
成员现在将错位。
回到Guid,从声明中看不出来,但它内部是由一些成员组成的。第一个是名为 _a
的私有(private)字段,它是一个 int。因此,Guid 需要 4 字节对齐。因此,需要 2 个额外的填充字节才能使您的结构在数组中使用时正确对齐。您需要在 S2 上使用 Pack=1 或 Pack=2 才能获得 18 个字节。
在 this answer 中了解有关结构的更多背景知识以及它们在 .NET 中的特殊处理方式.
关于c# - 包含 guid 的结构上的 Marshal.SizeOf 提供额外的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12572666/