C/C++中的struct字节对齐问题

字节对齐问题在面试笔试中经常碰到,自己也在这里经常碰到坑,今天索性把这方面搞清楚,记录自己这方面的学习过程。

大端小端法

机器的大端小端问题一直是一个常考的点,并且struct的内存布局问题和这个大端小端有很大关系,这里先看下机器的大端小端问题:
下面通过一张图来说明问题,假如一个变量int x的值为0x12345678,当在不同的机器上存储顺序是不同的
大端小端图
可以看到,大端机器上低地址存储的是高位,小端则恰恰相反。用一个C语言程序来测试你的机器是大端还是小端的好的方式如下:

show_bytes()
{
    int x = 0x12345678;
    unsigned char *p = (unsigned char*)&x;
    int i = 0;
    for(i = 0; i < sizeof(int);i++)
    {
        printf("%.2x",p[i]);
    }
    printf("\n");
}

这段代码可以看出当前系统是大端还是小端,在我的机器上显示的是78563412,因此我的电脑是小端模式。

struct 与union的对齐规则

  • struct或者union的数据成员对齐规则:第一个放在offset位置为0处,从第二个开始,该元素与前一个元素之间的填充是由该元素字长与#pragma pack(k)(k=1,2,4,8,16)中的k之间的小者来决定。如果本身为两者之间的小者的整数倍,则不进行填充。即除去第一个元素,其余的元素的开始位置是由两者之间的小者的整数倍来决定的
  • 整体填充完毕后,该struct整体大小是由pack(k)指定的k与数据元素里面最大字长之间的小者决定。
    下面举几个例子来说明字节对齐遵循的规则
#pragma pack(k)//k=1,2,4,8,16
    struct S4 {
        char x1;
        double x2;
        short x3;
        float x4;
        char x5;
    };
  cout<< sizeof(S4) << endl; 

可以打印k分别等于1,2,4,8,16时S4的占用的大小空间,可以得到的结果分别为

16
18
24
32
32 //和k为8的结果相同

k为1的时候,此时不进行对齐,因此为所有变量的字长之和。下面从k为2的时候开始分析
- k = 2 时,第一个元素从offset为0的地址开始,第二个元素是double占8个字节,和当前k=2对比,2较小,又因为第一个元素是char,只占用一个字节,因此第二个元素和第一个元素之间需要达到2的倍数,需要填充1个字节;再看x3,x3占用2字节和k=2相等,而x1和x2已经占用了10字节,为2的倍数,因此x3和x2之间不填充字节;再看x4,占用4字节,比k=2大,而前三个元素已经12字节,为2的倍数,因此不需要填充。最后一个元素也不用填充。整体为18字节。整体18个字节,是2的倍数,因此最后一个元素不需要填充。下面是内存布局图:
这里写图片描述
其它的情况和这个类似,可以对比着画出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值