• 深入理解类的填充规则


      struct/class中的成员变量所占总大小不是简单地将各个成员变量的大小相加,而是要考虑到读取效率,有时需要添加填充字节。
      比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那 么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。


      填充规则: (1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
            (2)结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节
            (3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。


      判断一个类的大小通常用到规则(2)和(3)。
    例子1:基本分析

    class Coo {
        char c;
        short s;
        int i;
        short s2;
    };

    首先c的偏移量是0,而0是1的整数倍,因此不用加填充;s的偏移量是1,而1不是2的整数倍,因此要填充1;
    i的偏移量是4,而4是4的整数倍,因此不用填充;s2的偏移量是8,而8是2的整数倍,因此不用填充。
    最后,在类coo中,最宽基本类型是int,大小是4,而目前我们的类大小为: 1 (+1) + 2 + 4 + 2 = 10,不是4的整数倍,因此要在最后填充2。


    例子2:空类

    class Coo {};

    空类的大小是1。如果coo的大小是0,就无法区别其他的空类了。


    例子3:有静态成员

    class Coo {
        static int i;
    };

    类的大小是1。静态数据成员不属于实例的一部分,而是放到了全局数据区。


    例子4:类嵌套

    class CooIn {
        int i;
        short s;
        int i2;
    };
    
    class Coo{
        char c;
        CooIn ci;
        double d;
    };

    首先分析被嵌套的CooIn的大小,易得为12,且最宽数据成员大小为4。然后以ci为分界点,前面的大小要为4的整数倍,因此为1 + 3,而后面
    的分析就没有什么特殊性了。注意,不能把CooIn在Coo内展开为

    class Coo{
        char c;
        int i;
        short s;
        int i2;
        double d;
    };

    要将CooIn看作一个整体,其传输单位为4,因此ci前在加上CooIn时,要保证是4的整数倍    

  • 相关阅读:
    spring 自定义事件发布及监听(简单实例)
    解析spring中的BeanFactory(看完会有收获)
    如何提高锁的性能
    spring MVC模式拦截所有入口方法的入参出参打印
    java基于feemarker 生成word文档(超级简单)
    数据库事务特性汇总
    如何让window.open()以post请求方式调用(巧妙解法)
    a标签添加背景图片的解决办法
    深入理解Django Admin的list_display, list_filter和raw_id_fields,filter_horizontal选项
    django配置log日志
  • 原文地址:https://www.cnblogs.com/programmer-kaima/p/4934566.html
Copyright © 2020-2023  润新知