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

C++結構體大小計算方法

編輯:關於C語言

注意:成員對齊有一個重要的條件,即每個成員按自己的方式對齊.其對齊的規則是,每個成員按其類型的對齊參數(通常是這個類型的大小)和指定對齊參數(這裡默認是8字節)中較小的一個對齊.並且結構的長度必須為所用過的所有對齊參數的整數倍,不夠就補空字節.


結構體(struct)的sizeof值,並不是簡單的將其中各元素所占字節相加,而是要考慮到存儲空間的字節對齊問題。先看下面定義的兩個結構體.

struct
{
char a;
short b;
char c;
}S1;struct
{
char a;
char b;
short c;
}S2;分別用程序測試得出sizeof(S1)=6 , sizeof(S2)=4可見,雖然兩個結構體所含的元素相同,但因為其中存放的元素類型順序不一樣,所占字節也出現差異。這就是字節對齊原因。通過字節對齊,有助於加快計算機的取數速度,否則就得多花指令周期。字節對齊原則結構體默認的字節對齊一般滿足三個准則:1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
2) 結構體每個成員相對於結構體首地址的偏移量offset,即每個成員的起始地址)都是成員自身大小的整數倍,如有需要編譯器會在成員之間加上填充字節internal adding);
3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節trailing padding)。
注意:當結構體成員裡面有數組成員時,如int a[10],要看成10個整形變量才參與計算。
通過這三個原則,就不難理解上面兩個struct的差異了.對於struct S1, 為了使short變量滿足字節對其准則(2), 即其存儲位置相對於結構體首地址的offset是自身大小(short占2個字節)的整數倍,必須在字節a後面填充一個字節以對齊;再由准則(3),為了 滿足結構體總大小為short大小的整數倍,必須再在c後面填充一個字節。
對於struct S2, 卻不必如上所述的填充字節,因為其直接順序存儲已經滿足了對齊准則。如果將上面兩個結構體中的short都改為int(占4個字節), 那麼會怎麼樣呢? 程序得出sizeof(S1)=12, sizeof(S2)=8
利用上面的准則,也不難計算得出這樣的結果。S1中在a後面填充3個字節、在c後面填充3個字節,這樣一共12個字節;S2中在a、b順序存儲之後填充兩個字節用以對其,這樣一共就8個字節。當然,在某些時候也可以設置字節對齊方式。這就需要使用 #pragma pack 。
#pragma pack(push) //壓棧保存
#pragma pack(1)// 設置1字節對齊
struct
{
char a;
short b;
char c;
}S1;
#pragma pack(pop) // 恢復先前設置如上所示,將對其方式設為1字節對齊,那麼S1就不填充字節,sizeof為各元素所占字節之和即4。這一點在從外部2進制文件中讀入struct大小的數據到struct中,是很有用的.另外,還有如下的一種方式:
· __attribute((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。
· __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際占用字節數進行對齊。


本文出自 “燃燒技術的活力” 博客,請務必保留此出處http://boyishachang.blog.51cto.com/3485129/1273323

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