zoukankan      html  css  js  c++  java
  • delphi中Record 和Packed Record的区别

    Record 和Packed Record 第一种不带packed关键字的结构体表明编译器编译时要求进行字对齐,而第二种带packed关键字的结构体表明编译器编译该结构体时不需要进行字对齐,这种方式对结构体中的字段访问会比第一种方式慢!但是更节约空间。有Packed 的占用内存小,但是速度慢一点。没Packed 的占用内存大,但是速度快一点  

         比如:        

         TA   =   record            

             a:   AnsiChar;            

             b:   Integer;        

         end;    

         和       

         TB   =   packed   record            

            a:   AnsiChar;            

            b:   Integer;        

         end;    

         中:    

         TA.b位于TA结构开始处第4个字节,   TB.b位于TB结构开始处第二个字节.   即TA结构中在TA.a和TA.b中间插了3个无用字节,   为TB.b在内存中的地址是按字对齐的--即这个地址能被4整除,   而TB中则没有这些无用字节,   但是TB.b不是字对齐的,   对它的访问比对TA.b慢.  

    例子1-----------------------------------------------------   

    type t=  packed record   和 type t=   record       

    a:AnsiChar;  {1}               a:AnsiChar;{8}   --因为a的长度不够一个字(8个字节),而紧接则的d为一个字(8个字节)所以要补齐8    

    d : double ;{8}                 d : double ;{8}    

    b:smallint;{2}                   b:smallint; {8}                 

    end;    :Sizeof(t) =11         end;    :  Sizeof(t) =24 的区别:看后面的注释{**} ;

    例子2------------------------------------ 

    type t=  packed record     和    type t=   record       

    a:AnsiChar;  {1}                    a:AnsiChar;   //因为a的长度为1个字节,后面的b为两个字节累加3个字节,

                                                          //再后面d为8 个字节,所以a+b要补齐到8个字节    

    b:smallint;{2}                       b:smallint; a+b占8个字节(即一个字)      

    d : double ;{8}                     d : double ;{8}              

    end;     :Sizeof(t) =11             end;    : Sizeof(t) =16 的区别:看后面的注释{**} ;

         在Windows中内存的分配一次是4个字节的。而Packed按字节进行内存的申请和分配,这样速度要慢一些,因为需要额外的时间来进行指针的定位。因此如果不用Packed的话,Delphi将按一次4个字节的方式申请内存,因此如果一个变量没有4个字节宽的话也要占4个字节!这样就浪费了。

    c/c++ struct内存对齐:
      成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.如果有#pragma pack(8),它虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.也就是说对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。实际上根据这些规则安排整个的内存布局的算法很简单,假设起始地址为0,开始安放第1个成员,然后找到下一个成员可以安放的起始位置,首先这个位置肯定在第一个成员之外,其次满足那些对齐因素。找到满足这两个条件的第一个位置即可。然后再考虑下一个成员,逐次进行下去。最后再考虑整个结构体的对齐因素,确定整个结构体的结束位置,这个位置的下个位置也就是下一个结构体的开始位置,保证它能够满足对齐。

    比如:
    struct MyStruct 

    char dda; 
    double dda1;   
    int type 
    };

    (简单说明) 
    struct MyStruct 

    char dda;//偏移量为0,满足对齐方式,dda占用1个字节; 
    double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8 
                 //的倍数,需要补足7个字节才能使偏移量变为8(满足对齐 
                 //方式),因此VC自动填充7个字节,dda1存放在偏移量为8 
                 //的地址上,它占用8个字节。 
    int type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍 
               //数,满足int的对齐方式,所以不需要VC自动填充,type存 
               //放在偏移量为16的地址上,它占用4个字节。 
    };//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构 
       //的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof 
       //(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为 
       //sizeof(double)=8的倍数。 
    所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。

    C++中的 struct                          相当于 delphi 的 record ,

    C++中的有#pragma pack 的struct  相当于 delphi 的 packed record 

  • 相关阅读:
    java,jenkins
    docker compose,link,Odoo
    nginx,docker反向代理
    centos7上安装docker-ce社区版
    Install Rancher server
    docker公司测试环境搭建总结
    ansible+docker
    桥接物理网卡,pipwork指定ip,外网连接,研究salt+docker
    20170605
    20170602
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/6564964.html
Copyright © 2011-2022 走看看