結構體的大小

2021-09-30 14:08:52 字數 2447 閱讀 1974

結構體中的成員可以是不同的資料型別,成員按照定義時的順序依次儲存在連續的記憶體空間。和陣列不一樣的是,結構體的大小不是所有成員大小簡單的相加,需要考慮到系統在儲存結構體變數時的位址對齊問題。看下面這樣的乙個結構體:

struct stu1

;先介紹乙個相關的概念——偏移量。偏移量指的是結構體變數中成員的位址和結構體變數位址的差。結構體大小等於最後乙個成員的偏移量加上最後乙個成員的大小。顯然,結構體變數中第乙個成員的位址就是結構體變數的首位址。因此,第乙個成員i的偏移量為0。第二個成員c的偏移量是第乙個成員的偏移量加上第乙個成員的大小(0+4),其值為4;第三個成員j的偏移量是第二個成員的偏移量加上第二個成員的大小(4+1),其值為5。

實際上,由於儲存變數時位址對齊的要求,編譯器在編譯程式時會遵循兩條原則:一、結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍) 二、結構體大小必須是所有成員大小的整數倍。

對照第一條,上面的例子中前兩個成員的偏移量都滿足要求,但第三個成員的偏移量為5,並不是自身(int)大小的整數倍。編譯器在處理時會在第二個成員後面補上3個空位元組,使得第三個成員的偏移量變成8。

對照第二條,結構體大小等於最後乙個成員的偏移量加上其大小,上面的例子中計算出來的大小為12,滿足要求。

再看乙個滿足第一條,不滿足第二條的情況

struct stu2

;成員k的偏移量為0;成員t的偏移量為4,都不需要調整。但計算出來的大小為6,顯然不是成員k大小的整數倍。因此,編譯器會在成員t後面補上2個位元組,使得結構體的大小變成8從而滿足第二個要求。由此可見,大家在定義結構體型別時需要考慮到位元組對齊的情況,不同的順序會影響到結構體的大小。對比下面兩種定義順序

struct stu3

算出sizeof(

stu3

)=1+8=9,但9不是int的整數倍故最終大小為12

struct stu4

算出sizeof(

stu4

)=4+4=8,8是int的整數倍故最終大小為8

如果結構體中的成員又是另外一種結構體型別時應該怎麼計算呢?只需把其展開即可。但有一點需要注意,展開後的結構體的第乙個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。看下面的例子:

struct stu5

ss;int k;

}結構體stu5的成員ss.c的偏移量應該是4,而不是 2。整個結構體大小應該是16。

四個重要的基本概念:

1.資料型別自身的對齊值:

對於char型資料,其自身對齊值為1,對於short型為2,對於int,float,double型別,其自身對齊值為4,單位位元組。

2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。

3.指定對齊值:#pragma pack (value)時的指定對齊值value。

4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。

例子分析:

分析例子b;

struct b

;對於結構體b,

先可以看出這個結構體的每乙個成員大小是1 4 2;

其次,再看結構體自身的有效對齊值為4;

每個成員自己的有效對齊值與結構體的有效對齊值比較,得出每個成員的有效對齊值為1 4 2;

有效對齊值決定了偏移量,得出每乙個成員的偏移量為0 4 8;

最後得出結構體的大小為最後乙個的大小與它的偏移量之和:8+2=10;

檢查發現10不是結構體自身有效對齊值(這裡是int型)的整數倍,故最後結構體的大小是12.

其實如果就這乙個就來說它已將滿足位元組對齊了, 因為它的起始位址是0,因此肯定是對齊的,之所以在後面補充2個位元組,是因為編譯器為了實現結構陣列的訪問效率,試想如果我們定義了乙個結構b的陣列,那 麼第乙個結構起始位址是0沒有問題,但是第二個結構呢?按照陣列的定義,陣列中所有元素都是緊挨著的,如果我們不把結構的大小補充為4的整數倍,那麼下一 個結構的起始位址將是0x0000a,這顯然不能滿足結構的位址對齊了,因此我們要把結構補充成有效對齊大小的整數倍.其實諸如:對於char型資料,其 自身對齊值為1,對於short型為2,對於int,float型別,其自身對齊值為4,,double自身對齊值為8,這些已有型別的自身對齊值也是基於陣列考慮的,只 是因為這些型別的長度已知了,所以他們的自身對齊值也就已知了.

同理,分析上面例子c:

#pragma pack (2) /*指定按2位元組對齊*/

struct c

;#pragma pack () /*取消指定對齊,恢復預設對齊*/

對於結構體c,

先可以看出這個結構體的每乙個成員大小是1 4 2;

其次,再看結構體自身的有效對齊值為2;

每個成員自己的有效對齊值與結構體的有效對齊值比較,得出每個成員的有效對齊值為1 2 2;

有效對齊值決定了偏移量,得出每乙個成員的偏移量為0 2 6;

最後得出結構體的大小為最後乙個的大小與它的偏移量之和:6+2=8;

檢查發現8是結構體有效對齊值2的整數倍,故最後結構體的大小是8.

(有刪改)

結構體的大小

對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各個硬體平台對儲存空間的處...

結構體的大小

typedef 定義型別 typedef unsigned long long uint64 定義型別,起外號 例如 typedef struct student student 注意 typedef int pfun int,int 函式指標 指向函式的指標 typedef int pint de...

結構體大小

含有基本型別的結構體的大小所對應的最終決定因素是結構體內自身成員的分布。成員不同的分布將導致含有相同成員結構體大小的不同,每個成員的對齊都是以緊接著後面的乙個為參考的,如果緊接著的大於對應指定,就以緊接著的為對齊因子,否則將聯絡周圍的具體情況進行對齊,而且對齊因子只有三種型別 1,2,4。對於最後一...