字节对齐问题

 
为了能使 CPU 对变量进行高效快速的访问,变量的起始地址应该具有某些特性,
即所谓的 对齐 。例如对于 4 字节的 int 类型变量,其起始地址应位于 4 字节边界上,
即起始地址能够被 4 整除。变量的对齐规则如下( 32 位系统):

Type
Alignment
char
在字节边界上对齐
short (16-bit)
在双字节边界上对齐
int and long (32-bit)
4 字节边界上对齐
float
4 字节边界上对齐
double
8 字节边界上对齐
 
字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
 
1)
结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成
  员之间加上填充字节;例如上面第二个结构体变量的地址空间。
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员
   之后加上填充字节。
例如 :

struct s1
{
 char a;
 short b;
 char c;
};
  在上述结构体中, size 最大的是 short ,其长度为 2 字节,因而结构体中的 char 成员 a c 都以 2
为单位对齐, sizeof(s1) 的结果等于 6
      
                              a               b              c
s1
的内存布局         1*              11              1*  (* 表示填充的字节 , 下同 )
若改为
struct s1
{
 char a;
 int b;
 char c;
};
  其结果显然为 12
                                   a               b                c
s1
的内存布局         1***           1111           1***
 
2.
又如 :
       struct S1{
                  char a;
                  long b;
               };
       struct S2 {
                  char c;
                  struct S1 d;
                  long long e;
                 };
sizeof(S2)
结果为 24;
分析如下 :
        
根据上面的分析 sizeof(s1)=8;
         s1
的内存布局         a           b
                                       1***         1111 
         S2
,c S1 中的 a 一样 , 1 字节对齐 , d 是个结构 , 它是 8 个字节 , 它按什么对齐呢 ?
于结构来说 , 它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个 ,S1 的就是 4. 所以 ,
成员 d 就是按 4 字节对齐 . 成员 e 8 个字节 , 它是默认按 8 字节对齐 , 和指定的一样 , 所以它对到 8 字节
的边界上 , 这时 , 已经使用了 12 个字节了 , 所以又添加了 4 个字节的空 , 从第 16 个字节开始放置成员
e. 这时 , 长度为 24, 已经可以被 8( 成员 e 8 字节对齐 ) 整除 . 这样 , 一共使用了 24 个字节 .
         S2
的内存布局         c                d                          e
                                     1***       1***1111****         11111111
再看两个结构体成员比较复杂的例子 :
  Typedef struct student
 
{
 
       Char name[10]
 
       Long sno;
 
       Char sex;
 
       Float score [4];
 
} STU;
sizeof(STU)=?
STU
的内存布局              name            sno       sex         score
                              1111111111**      1111       1***       1111111111111111
sizeof(STU)=10+2+4+1+3+16
如果我们把 STU 中的成员改一下顺序 :
 Typedef struct student
 
{
 
       Char name[10]
       Char sex;
 

       Long sno;
       Float score [4];
 
} STU;
STU
的内存布局         name         sex       sno        score
                             1111111111      1*       1111       1111111111111111
sizeof(STU)=10+2+4+16
注意:
1 对于空结构体, sizeof == 1 ;因为必须保证结构体的每一个实例在内存中都
有独一无二的地址。
2 结构体的静态成员不对结构体的大小产生影响,因为静态变量的存储位置与
结构体的实例地址无关。
例如:
struct {static int I;} T;
sizeof(T) == 1;
struct {char a; static int I;} T1;
sizeof(T1) == 1;
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值