C# 内存对齐
[StructLayout(LayoutKind.Sequential)]
unsafe struct B{
// public int field1;
public double field2;
public string field3;
byte* field4;
byte field5;
nint field6;
byte field7;
byte field8;
short field9;
short field10;
short field11;
// decimal field7;
}
sizeof(B)=48 ;
和LayoutKind.Auto的结果一样的, 反复试了几遍感觉似乎和字段的顺序没关系,打开field1 的话,它还是会和别的不足一个pack的字段接合。。 除非出现转弯
那么我来名词解释下,pack 就是说内存地址的长度,64位=8字节在这样的内存平台上 pack=address length=8 byte , 在32位内存平台上,是4 byte , C#内存对齐的规则 大致是这样的,从office 0开始往后依次排,按address len来计算,只要多个字段的长度相加没出现“转弯” 或 称为“折叠”那么这种 多个字段放入一个 address len(pack)之内的情况就是会发生的,应该是自动发生的,比方一个 byte 类型是 1,一个short 是2,一个 int是4 这些字段都小于 memory address len 所以多个这样的字段可以放入一个 pack里,并且这是自动的,但是若 一个Int + double这就不行,因为4+8 =12 已经大于一个pack =8了,所以出同现叠这就不允许 (这个规则 是我猜测的,是符合逻辑的推测)因为若出现各种折叠则 让字段的读取和识别将变得异常复杂 和困难
[StructLayout(LayoutKind.Sequential)] struct C1{ int filed1; double field2; short field3; } [StructLayout(LayoutKind.Auto)] struct C2{ int filed1; double field2; short field3; } [StructLayout(LayoutKind.Sequential)] struct C3{ int filed1; short field3; double field2; } [StructLayout(LayoutKind.Auto)] struct C4{ int filed1; short field3; double field2; } unsafe{ Console.WriteLine("Sequential,C1:int,double,short sizeof:{0}",sizeof(C1)); Console.WriteLine("Auto,C2:int,double,short sizeof:{0}",sizeof(C2)); Console.WriteLine("Sequential,C3:int,short,double sizeof:{0}",sizeof(C3)); Console.WriteLine("Auto,C4:int,short,double sizeof:{0}",sizeof(C4)); }
Sequential,C1:int,double,short sizeof:24
Auto,C2:int,double,short sizeof:16
Sequential,C3:int,short,double sizeof:16
Auto,C4:int,short,double sizeof:16
using System.Runtime.InteropServices; unsafe struct A{ public int field1; public double field2; public string field3; public int Field1 { get => field1; set => field1 = value; } public double Field2 { get => field2; set => field2 = value; } public void M1() => Console.WriteLine("M1"); } [StructLayout(LayoutKind.Sequential)] unsafe struct B{ public int field1; public double field2; public string field3; byte* field4; byte field5; nint field6; byte field7; byte field8; short field9; short field10; short field11; // decimal field7; } [StructLayout(LayoutKind.Auto)] unsafe struct B2{ public int field1; public double field2; public string field3; byte* field4; byte field5; nint field6; byte field7; byte field8; short field9; short field10; short field11; // decimal field7; } unsafe{ var x1=new A(); var p1 = &x1; p1->Field1=10; Console.WriteLine(x1.Field1); p1->M1(); Console.WriteLine(sizeof(A)); Console.WriteLine(sizeof(B)); Console.WriteLine(sizeof(B2)); }
10
M1
24
48
48
为什么 sizeof(B) 和sizeof(B2) 都为48 没搞懂,不应该说 sizeof(B) = 56吗? 谁能解释
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?