2009-12-09 36 views
3

可能重複:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?C++結構尺寸:2 + 4 + 2 + 2 + 4 = 16

爲什麼這種結構的16個字節的sizeof();?我正在編譯g ++。

struct bitmapfileheader {  
    unsigned short bfType; 
    unsigned int bfSize; 
    unsigned short bfReserved1; 
    unsigned short bfReserved2; 
    unsigned int bfOffBits; 
    }; 
+3

Dupe:http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – 2009-12-09 20:29:41

+1

http:///en.wikipedia.org/wiki/Sizeof#Structure_padding – 2009-12-09 20:29:56

+1

誰說short是2而int是4? – 2009-12-09 20:35:53

回答

5

我認爲你的編譯器對字段使用4字節的allignment。

+0

只有'int'字段。 – Zooba 2009-12-09 20:30:04

7

結構中的各個字段需要適當對齊。編譯器將填充結構中的額外空間以滿足對齊要求。

如果你不想要這個,你可以使用宏UNALIGNED

+6

我不認爲'unaligned'是一個關鍵字。這將是編譯器特定的。 – GManNickG 2009-12-09 20:29:04

+1

答案很好,但'unaligned'不是C++關鍵字。 – coppro 2009-12-09 20:29:25

+0

具體來說,在這種情況下,它看起來像在第一個「int」之前填充2個字節,以將其與4字節邊界對齊。短褲對齊到2個字節的邊界。 – 2009-12-09 20:31:26

12

這是因爲4字節整數與4字節邊界對齊,所以在bfType之後有2個字節的填充。

8

對齊。 可能在您的平臺上,int必須是4byte對齊,並且shorts是2byte對齊。

+0 -1 : bfType 
+2 -3 : <padding> 
+4 -7: bfSize 
+8 -9: bfReserve1 
+10 -11: bfReserve2 
+12 -15: bfOffBits 
------------- 
16 bytes 

對齊是好的,因爲未對齊的結構需要爲許多架構額外的工作。

0

因爲內存的方式分配,會有一個短暫

+1

確實,這是一個很好的建議。但是,這裏的應用程序涉及處理.bmp文件,所以這不是一個選項。 +1無論如何;-) – 2009-12-09 20:34:40

0

這之後填充是由於定位 - 編譯器必須做一些填充。

1

U可以編譯包裝結構,以避免填充

1

ISO C++ 03,9.2 [class.mem]/12:(非聯合)的

非靜態數據成員聲明的類沒有介入的訪問說明符被分配,以便後面的成員在類對象內有更高的地址。未指定由訪問說明符分隔的非靜態數據成員的分配順序(11.1)。 執行對齊需求可能會導致兩個相鄰成員不能立即被分配;所以可能需要管理虛擬功能(10.3)和虛擬基類(10.1)的空間。

2

這個問題是由於一個名爲的對齊。在許多情況下,希望將一個數字放在地址中,該地址是以字節爲單位的數字大小的倍數(達到某個最大值,通常是平臺的指針大小)。這樣放置的變量被稱爲,其與n字節邊界對齊,其中n是數字。這個確切的影響取決於處理器。如果數據正確對齊,許多處理器會更快地執行數學運算。有些甚至不能在不適合的數據上執行操作(有時甚至是加載操作) - 爲了處理這些數據,它必須被加載到兩個寄存器中,然後需要執行一系列位移和掩碼以獲得一個可用的值,然後它需要被放回。想想它就像在兩個桶中分別存儲一半的int,並且需要將它們放在一起使用,而不是簡單地將整個int存儲在一個桶中。

在你的情況,最初的bfType可能需要對齊到一個2字節的邊界,而bfSize可能需要對齊到一個4字節的邊界。編譯器必須通過將整個結構對齊到4個字節並在bfTypebfSize之間留下2個未使用的字節來適應這一點。

但是,在同一個系統上編譯時,填充可能會一致,可能取決於編譯器選項和所使用的特定ABI(通常,除非您試圖製作東西,否則您在同一平臺上安全不相容)。您可以自由地使用相同的前5個成員創建另一個結構,並且它們將佔用另一個結構的16個字節,並且位置完全相同。

如果你真的需要避免這種行爲,你將不得不檢查你的編譯器文檔。大多數編譯器提供一個屬性或關鍵字來聲明一個變量沒有對齊,另一個指示一個結構不應該有填充。但這些在事物的一般過程中很少需要。