[英]How does sizeof calculate the size of structures
我知道,由於對齊,在32位體系結構上,一個char和一個int被計算為8個字節,但是最近我遇到了一種情況,其中sizeof運算符將3個短褲的結構報告為6個字節。 代碼如下:
#include <iostream>
using namespace std ;
struct IntAndChar
{
int a ;
unsigned char b ;
};
struct ThreeShorts
{
unsigned short a ;
unsigned short b ;
unsigned short c ;
};
int main()
{
cout<<sizeof(IntAndChar)<<endl; // outputs '8'
cout<<sizeof(ThreeShorts)<<endl; // outputs '6', I expected this to be '8'
return 0 ;
}
編譯器:g ++(Debian 4.3.2-1.1)4.3.2。 這真的使我感到困惑,為什么不對包含3個短褲的結構強制執行對齊?
那是因為int
是4個字節,並且必須與4個字節的邊界對齊。 這意味着包含int
ANY struct
也必須至少對齊4個字節。
另一方面, short
是2個字節,只需要對齊2個字節的邊界即可。 如果包含short
的struct
不包含任何需要較大對齊的內容,則該struct
還將對齊2個字節。
這真的使我感到困惑,為什么不對t強制執行對齊
您希望它具有什么對齊方式?
短褲可以在2個字節的邊界上對齊,而不會造成不良影響(假設此處使用通用的x86編譯器。)。 因此,如果您創建一個struct ThreeeShorts
數組,那么大小為6的結構就可以了,因為該數組中的任何元素都將從2字節邊界開始。
您的struct IntAndChar
包含一個int,int需要4個字節的對齊方式,因此,如果您創建一個struct IntAndChar
的數組, struct IntAndChar
其大小必須為8,以便下一個元素在4個字節的邊界上對齊。
如果我們不考慮數組,那么struct IntAndChar
為5個字節就沒關系,當您在堆棧中創建一個堆棧或將其用作復合成員時,編譯器只會從4字節邊界開始分配它另一個結構。
您總是可以通過執行sizeof(arrayofT)/ sizeof(T)來獲取數組中元素的數量,並且保證數組元素可以相鄰存儲,從而可以通過步進N * sizeof(arrayelementtype)來獲取第n個元素。 )從頭開始算起字節,這就是您會在末尾看到struct的主要原因。
我不知道您將char
或int
計算為“ 8字節”的想法。 不,每種類型都是根據其大小計算的:在32位平台上, char
為1, int
為4(不是8,而是4)。 每種類型的對齊要求通常與其大小相同(盡管不必如此)。
因此,當結構包含相同類型的成員時,該結構的總大小通常將是其成員大小的確切總和:3個char
的結構將具有3的大小,而2個結構將具有2個char
的結構int
的大小為8。
顯然,您平台上的short
類型的大小為2,因此,預計3個short的結構的大小為6,這正是您所觀察到的。
但是,當您的結構包含不同類型的成員時,則不同類型的對齊要求之間的差異將發揮作用。 如果下一個字段的對齊要求比上一個字段的對齊要求嚴格,則編譯器可能必須在這些字段之間添加一些填充字節(以正確對齊下一個成員),這將影響結構的最終大小。 同樣,編譯器可能必須在結構的最后一個成員之后添加一些額外的填充字節,才能滿足數組中的對齊要求。
例如,如下所示的結構
struct S {
char c;
int i;
};
將最有可能在您的平台上占用8個字節,因為在char
成員之后需要3個填充字節。 注意, char
計為1, int
為4,而它們之間的額外3個填充字節使之為8。
還要注意,這可能很容易引入結構的最終大小對成員聲明順序的依賴性。 例如,這種結構
struct S1 {
char c1;
int i;
char c2;
};
您平台上的尺寸可能為12,而這一尺寸
struct S2 {
int i;
char c1;
char c2;
};
將僅占用8個字節。 最后一個示例旨在說明該結構的最終大小無法用每個成員“計數”多少字節來表示。 成員之間的關系也很重要。
它完全取決於實現,但是如果您的系統可以訪問結構中三個short
的任何一個而不必擔心對齊,那么它可以訪問ThreeShorts
數組中的任何short
,因此可以訪問任何數據成員,而不必擔心對齊。 因此,無需更嚴格地對齊結構。
對於IntAndChar
例如, int
大概有大小4和實施涉及其對齊。 為了確保IntAndChar
數組中的每個int
成員正確對齊,必須填充該結構。
所述sizeof
陣列T[n]
被精確地定義為sizeof(T) * n
。
該鏈接應該有幫助: http : //en.wikipedia.org/wiki/Data_structure_alignment
在ThreeShorts
所有成員都是兩個字節對齊的。
是的,我有同樣的問題。 我有以下結構
struct Node{
short digit;
Node* next;
};
cout<<":"<<sizeof(Node)<<":"<<sizeof(short)<<":"<<sizeof(Node*)<<endl;
這給了我:: 8:2:4 ?? 為什么該結構的總和= 8,但是各個元素不求和? 這是因為內存對齊,因此在內存中填充了額外的2個字節用於對齊。 謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.