sizeof 和 alignment(对齐)

类别:编程语言 点击:0 评论:0 推荐:

sizeof 和 alignment(对齐)


1: alignment的定义
   alignment指的是对象的开始地址必须满足条件:
  
   >>#pragma pack(push, 1)
   <<任何地址

   >>#pragma pack(push, 2)
   <<偶数地址

   >>#pragma pack(push, 4)
   <<地址必须是4的倍数

   >>#pragma pack(push, 8)
   <<地址必须是8的倍数

2: 基本类型T的alignment(T)
   对齐值就是上面所说的1, 2, 4, 8

   现在对应于每个类型T, 都有一个alignment(T)和T对应,
   这个对应关系究竟如何呢:

   (以下针对我们现在所碰到的编译器而言)
  
   << char -->  1 (永远是1)

   << short
      #pragma pack(1) --> 1
      #pragma pack(2) --> 2
      #pragma pack(4) --> 2 // 呵呵,这里是关键
      ...                      --> 2

   << int
      #pragma pack(1) --> 1
      #pragma pack(2) --> 2
      #pragma pack(4) --> 4 // 呵呵,这里是关键
      ...                      --> 4
      ...
  
   这里就有了一个概念, 我们尚且将其命名为
   internal_PACK(T):
      internal_PACK(char) = 1
      internal_PACK(short) = 2
      internal_PACK(int) =4
      internal_PACK(int64) = 8
      ...
   和当前编译器的对齐方式无关。

   编译其当前设置的#pragma pack(n)值我们命名为
      PACK (= n)

   那我们就有公式:
    if (internal_PACK(T) < PACK)
      alignment(T, PACK) = internal_PACK(T)
    else
      alignment(T, PACK) = PACK

   下面的这个对任何类型T都成立:
   alignment(T) <= PACK                          --------------------------------#1

 
3  struct(or class)类型ST的alignment(ST)

   alignment(ST) = max { alignment(T) | T 是ST的data member 的类型 }

 
4  举例
   <<
      #pragma pack(1)
      struct A
      {
        ....
      };           
      由#1, 在pack(1)的情况下所有的 alignment(type)≡1

   <<
      #pragma pack(4)
      struct A
      {
         char ch;
         short sh;
      };
      alignment(ch) = 1
      alignment(sh) = 2
      alignment(A)  = 2

   <<
      #pragma pack(8)
      struct A
      {
        char ch;
        int n;
        char ch;
      };
      alignment(n) = 4
      alignment(A) = 4

   <<
      #pragma pack(2)
      struct A
      {
        char ch;
        int n;
        char ch;
      };
      alignment(n) = 2
      alignment(A) = 2

5:  sizeof(T)
    <<
      对基本类型来说 
         sizeof(T)   = internal_PACK(T)
   
    <<
      对结构类型ST来说 
      把最后一个数据成员m_last去掉后形成的结构叫ST~
      sizeof(ST) = sizeof(ST~) + last_size + patch        
      其中
   <<
             last_size = member_patch + sizeof(m_last)
             member_patch = [sizeof(ST~) 到 比它的alignment(m_last)倍数的最小距离] ;      
 
          <<
             patch     = [sizeof(ST~) + last_size到比它大的alignment(ST)倍数的最小距离]

     其中
   <<
             member_patch是因为m_last要地址对齐alignment(m_last)
         
          <<
             patch 是因为如果声明一个数组的话:
       ST st[2];
             为了满足
         1:  st[1] 地址alignment(ST)对齐
                        2:  sizeof(st) = sizeof(st1) + sizeof(st2)
             关键是第二条
             所以需要patch把余下的空间补满。
            

本文地址:http://com.8s8s.com/it/it28968.htm