结构体存储空间大小计算&字节对齐

出处:http://pppboy.blog.163.com/blog/static/30203796201082494026399/

        http://blog.csdn.net/loverooney/article/details/38262709?ticket=ST-178747-gWh0gNJ1Qnzf7zCWMua7-passport.csdn.net

感谢博主的分享。

    在看《C/C++程序员面试指南》(作者:杨国祥)中的结构体对齐时,原语句“每个数据都要对照结构体中最大数据的最小公倍数对齐”,和程序员面试宝典中所写有出入,宝典中所写“每个成员的存储起始位置能够被该成员的大小整除”。在网上查阅了几篇别人写的文章,以及在VS2010中仿真得出的结果证明《C/C++程序员面试指南》中描述错误。将一些细节知识点整理如下,方便回顾。

1、说明

  字节对齐的基本原则:

    1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

    2)成员按照声明的顺序存储,每个成员相对于首地址的偏移量是该成员大小的整数倍;

    3)整个结构体的总大小是最宽基本类型成员的整数倍。

    对于结构体A的某成员是结构体B:

    结构体A的大小是包括A中其他基本类型成员和B中所有基本类型成员中宽度最大的成员的整数倍。首先单独计算出B的总大小,设为M。接着计算A的总大小,在A中,B的起始地址能够被B中最宽数据成员大小整除,如若不够,需要补充空字节。在A中,B所占大小为M。B之后的数据的起始地址能够被该数据的大小整除,如若不够,需在B之后补充空字节。

    结构体中包含数组时,在计算最宽成员长度时,将数组元素当成独立的个体。例:

    struct sample1{

    int a;

    char b[5];

    }

   sample1的最宽长度为int型,4个字节。sample1的大小为:4+5+补3个字节 = 12个字节。

    空结构体占用1字节。

2、计算方法

以32字节的系统为例

sizeof(char) = 1; sizeof(int) = 4; sizeof(long) = 4; sizeof(double) = 8;


//空   sizeof(S0) = 1;

 struct S0{  };  


 //sizeof(S1) = 8. b为字节最宽的数据,占用4个字节。a起始地址为0,占用1个字节,补3个字节,b的起始地址为4,占用4个字节,4~7。共8字节。

 struct S1{   

    char a;   

    long b;   

 }; 


//sizeof(S2) = 8. b为字节最宽的数据,占用4个字节。起始地址为0,0~3,a占用1个字节,起始地址为4,为了使总大小为b的整数倍,a补充3个字节。共8个字节。 

struct S2{   

    long b;   

    char a;   

}; 


//sizeof(S3) = 16. 将S1的成员代入,最宽数据为S1.b,4个字节。c占用1字节,d的起始地址要能够被d中最宽数据大小整除,在c后补充3空字节,d占用8字节,e占用4字节。共16字节。若将long e 换为double e,则最宽数据为e,8字节。

c占1字节+补3字节+d占8字节 = 12字节,不能被e的8字节整除,在d后需补4个空字节。

总大小为:12+4+8 = 24字节

struct S3 {   

    char c;   

    struct S1 d;//结构体   

    long e;   

}; 


//sizeof(S4) = 8,static存储在静态存储区域内,不算在内。

struct S4{   

    char a;   

    long b;   

    static long c; //静态   

};


//sizeof(S5) = 16. 最宽数据为b,name按照单个元素的大小1字节与其他数据进行比较。a占1字节,补3字节,0~3,b占4字节,4~7,name占5字节,不能被8整除,需在b后补2字节,此时,共15字节,不能被4整除,在name后补1字节。总大小为16字节。

struct S5{   

    char a;   

    long b;   

    char name[5]; //数组   

}; 


//sizeof(student0) = 16,最宽数据为num,4字节。name5字节,补3字节,num4字节,score2字节,补2字节。总大小为16字节。

struct student0   

{   

    char name[5];   

    int num;   

    short score;   

};  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值