随笔 - 73  文章 - 1  评论 - 16  阅读 - 79594

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吗? 谁能解释

posted on   ProjectDD  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示