当前位置 : 主页 > 网络安全 > 测试自动化 >

看的懂的字节对齐分析

来源:互联网 收集:自由互联 发布时间:2021-06-22
#写在开头, 编译器的对齐值为8byte 如题, 首先说一下为什么需要字节对齐, 这个似乎有些浪费空间, 那就先上一下比较书面的解释: 1.平台要求, 某些CPU只能访问地址为偶数的内存地址, 这

#写在开头, 编译器的对齐值为8byte

  如题, 首先说一下为什么需要字节对齐, 这个似乎有些浪费空间, 那就先上一下比较书面的解释:

    1. 平台要求, 某些CPU只能访问地址为偶数的内存地址, 这个时候你把数据放在奇数地址, 就会报错

    2. 性能要求, 这个跟寄存器有关系, 有些数据不对齐的话需要使用寄存器的次数会增多  

   说点通俗的, 就像一本书, 每页都有字, 但是不一定要写满; 写太满了, 没有章法, 看不了.

 

  下面, 先说明三个概念:

    1. 自身对齐值: 比如, short为2byte, double为8byte

    2. 指定对齐值: 编译器自己决定的; 或者程序员自己决定的

1 #pragma pack (n)
2 ***
3 ***
4 #pragma pack ()

    那么2, 3行内部的数据指定对齐值便是n

    3. 有效对齐值: 上面两个值的最小值

 

  对齐的规则呢:  

    1. 数据本身存储的地址应该是, 数据本身有效对齐值的整数倍

    2. 对于结构体而言, 由于1这条规则, 以及有结构体数组的存在, 所以结构体本身的有效对齐值为内部             数据有效对齐值的最大值.

 

  这么说还是比较抽象, 我们上点例子

1 struct A {
2    char a;
3    int b;   
4 };

首先a的自身对齐值为1, 制定对齐值为8, 那么有效对齐值为min{1, 8} = 1

  0x0     0x1     0x2     0x3      a      

接下来, 需要把b放进去, 他的地址应该时自身有效对齐为min{4, 8} = 4, 所以0x1, 0x2, 0x3都存不了,得从0x4开始存储

  0x0     0x1     0x2     0x3     0x4     0x5     0x6     0x7      a          b    b    b    b

如上, 很简单对吧, 下面讲一下规则2, 给结构体A加个char c

1 struct A {
2    char a;
3    int b;
4    char c;     
5 };

那么有趣的事情就会发生, a的有效对齐值为1, b的为4, c的为1, 那么A的就是4, 所以c的后面3个单元会被占用, 想一想, 如果不这样补齐的话, 你想想对于结构体数组的第二个元素的b他的地址就不是4的整数倍了.

 0x0   0x1   0x2   0x3   0x4   0x5   0x6   0x7   0x8   0x9   0xA   0xB    a         b   b   b   b   c       

 

所以, 究其根本, 所有的一切都是为了满足第1条规则.

 

那么再来如果把b换成double类型的呢?

1 struct A {
2    char a;
3    double b;
4    char c;     
5 };

那么a的有效对齐值为1, b为8, c为1, A为8, 那么整体应该占24byte

 0x0   0x1   0x2   0x3   0x4   0x5   0x6   0x7   0x8   0x9   0xA   0xB   0xC   0xD   0xE   0xF   0x10   0x11   0x12   0x13   0x14   0x15   0x16   0x17    a                 b   b   b   b   b   b   b   b   c              

光说不练假把式, 我们上几道题目

 1 #pragma pack (4)
 2 struct S1 {
 3     char a;
 4     double b;
 5 };
 6 
 7 struct S2 {
 8     char a;
 9     S1 s;
10     char b;
11     char c;
12 };
13 
14 struct S3 {
15     int a;
16     char b[10];
17 };
18 #pragma pack ()

注意指定对齐值被改为了4, 拿自己的IDE试试吧!

有问题, 请联系[email protected]

网友评论