程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 結構體的sizeof,結構體sizeof

結構體的sizeof,結構體sizeof

編輯:C++入門知識

結構體的sizeof,結構體sizeof


首先有幾條規則:

1. 結構體的成員相對於結構體的偏移量,是該成員所包含的最大簡單類型(指占用內存數)的整數倍(如果該成員本身又是一個結構體,就要遞歸查找其簡單類型,簡單類型就是char short int float double,long)

  比如struct a1{

       char a[5];

       int b;

     }aa;

    struct a2{

       double a;

       char b;

       a1 c;

      char d;

      }bb;

     此例中,aa.b相對於aa的偏移值是int的整數倍,所以aa.b的偏移值是8,aa.a後面有三字節填充;

    a2中bb.c的偏移值是a1所含的最大簡單類型的整數倍,a1包含的最大簡單類型是int,所以bb.c的偏移值是4的倍數,所以bb.c的偏移值是12,char類型的偏移值是1的倍數,double偏移值是8的倍數。long的長度根據規范,sizeof(long)>=sizeof(int),我的64位機器,vc2005,發現int=long=4字節,64位數據類型必須使用longlong或者其他windows自己定義的類型。

 

2. 結構體的最終大小,還要通過在結構體的末尾填充字節,使得結構體大小是結構體最大簡單類型(如果需要遞歸查詢簡單類型的話就要遞歸取出最大簡單類型)的整數倍

上述例子中,bb的大小,必須是8的整數倍. aa的大小為12,a1類型的成員在結構體中的起始位置應該是4的整數倍。這樣,a2的大小就是8+1+offset(bb.c) + sizeof(a1) + sizeof(d)+padding = 12+sizeof(a1)+1+ padding = 25+padding = 8的倍數, 所以sizeof(a2)應該取整到32,最後填充了7個字節。

3. 聯合類型union也是類似,union的成員的起始偏移(這是指,當union作為復合結構的成員變量時,相對於所在復合體)也要對齊到該成員所含最大簡單類型的整數倍上,union的最終大小也要補齊到最大簡單類型的整數倍上

比如union b1{

       char a[5];

       int b;

   };

    struct b2{

       char a[3];

       b1 b;

     char c;

     };

則b1的大小為8(最終大小要對齊到int類型的整數倍上), b2中的b的偏移值,應該是b的子成員的最大簡單類型的倍數,也就是b的偏移是4的倍數,所以b的偏移是4,b2的大小為12,b2的成員c的末尾還要補上3個字節,保證b2的大小是其成員中最大簡單類型的整數倍。

4. 如果加入了#pragma pack(n) , 這裡n只能=1,2,4,8,16... 那麼, 之前的“最大簡單類型”的計算就要變成 “最大簡單類型”的大小和n的最小值

比如

#pragma push //保存一下當前的對齊值

#pragma pack(4)

struct testT

{

char a1;

double a2;

        char a3;

};

#pragma pop //恢復編譯期記憶的對齊值

那麼,計算 sizeof(testT)== 16,默認應該是計算為24。這裡,a2偏移不在是8的倍數,而是min(sizeof(dobule), 4) = 4, 所以a2的偏移是4。從這裡也可以看出來,由於最大簡單類型是double=8或者64位的longlong=8, n>=16沒有意義(一般來說,除非你還有更大的簡單類型,16字節的超級cpu。。。)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved