Delphi中的内存对齐 与 Packed关键字

来源:互联网 发布:上海办网络宽带哪家好 编辑:程序博客网 时间:2024/05/16 08:53
 

以delphi为例:
TTest = record
c1: char;
i1: Integer;
c2: char;
c3: Char;
end;
这个结构如果用sizeof取其占用的内存大小,是多少呢,是1+4+1+1=7么,不是,是4*3 = 12; 这是因为32位编译的时候,默认结构会自动内存对齐(32bit = 4byte)。

如果要想让这个结构占用7个字节的话,必须加上packed关键字。如下:
TTest = packed record
c1: char;
i1: Integer;
c2: char;
c3: Char;
end;

 

在windows中内存的分配一次是4个字节的。而packed按字节进行内存的申请和分配,这样速度要慢一些,因为需要额外的时间来进行指针的定位。因此如果不用packed的话,delphi将按一次4个字节的方式申请内存,因此如果一个变量没有4个字节宽的话也要占4个字节!这样就浪费了,你可以用packed关键字取消这种优化。

例子:  
 type  
         myrec   =   packed   record  
         n1   :   integer;         4个字节  
         n2   :   shortint;       1个字节  
 end;  
 sizeof(myrec)------     5  
   
 type  
         myrec   =   record  
         n1   :   integer;  
         n2   :   shortint;  
 end;  
 sizeof(myrec)------     8

 

Record的数据各个字节都是对齐的,数据格式比较完整,所以这种格式相对packed占用的内存比较大,
但是因为格式比较整齐,所以电脑读取这个类型的数据的时候速度比较快。

而Packed Record对数据进行了压缩,节省了内存空间,当然他的速度也变的慢了。

  type  
      //    Declare    an    unpacked    record  
      TDefaultRecord    =    Record  
          name1        :    string[4];  
          floater    :    single;  
          name2        :    char;  
          int            :    Integer;  
      end;  
      //    Declare    a    packed    record  
      TPackedRecord    =    Packed    Record  
          name1        :    string[4];  
          floater    :    single;  
          name2        :    char;  
          int            :    Integer;  
      end;  
  var  
      defaultRec    :    TDefaultRecord;  
      packedRec      :    TPackedRecord;  
  begin  
      ShowMessage('Default    record    size    =    '+IntToStr(SizeOf(defaultRec)));  
      ShowMessage('Packed    record    size    =    '+IntToStr(SizeOf(packedRec)));  
  end;  
   
    Default    record    size    =    20  
    Packed    record    size    =    14  

不过,对于现在的操作系统来,packed Record 节省的那些空间已不用考虑他了。除了做DLL(不用packed容易造成内存混乱)和做硬件
编程时(比如串口)编程时必须用到packed Record,其它情况都可以用Record

原创粉丝点击