C++中字节对齐问题

一. 为什么需要字节对齐

        计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。

二. 结构体内存对齐的规则【未指定#pragma pack】
  1. 第一个成员起始于0偏移处;
  2. 每个成员按其类型大小和指定对齐参数n中较小的一个进行对齐;
  3. 结构体总长度必须为所有对齐参数的整数倍;
  4. 对于数组,可以拆开看做n个数组元素。
三. 具体举例(未指定#pragma pack):

例1:

		struct {
                 short a1;
                 short a2;
                 short a3;
                }A;
          struct{
                 long a1;
                 short a2;
                }B;

sizeof(A) = 6; 这个很好理解,三个short都为2。
sizeof(B) = 8; long为4,short为2,整个为8,因为规则3。

例2:

		struct A{
                  int a;
                  char b;
                  short c;
                  };
        struct B{
                  char b;
                  int a;
                  short c;
                  };

sizeof(A) = 8;sizeof(B) = 12。

例3:

			    struct A{
                     int a;
                     double b;
                     float c;
                    };
                struct B{
                     char e[2];
                     int f;
                     double g;
                     short h;
                     struct A i;
                    };

sizeof(A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
sizeof(B) = 48;

四. 具体举例(指定#pragma pack):
#pragma pack (2) /*指定按2字节对齐*/
struct C
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/

第一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1=0;第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续字节中,符合0x0002%2=0。第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序存放在0x0006、0x0007中,符合0x0006%2=0。所以从0x0000到0x00007共八字节存放的是C的变量。又C的自身对齐值为4,所以C的有效对齐值为2。又8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8.

参考链接:https://blog.csdn.net/cclethe/article/details/79659590

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

. . . . .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值