2012-04-12 102 views
0

比方說,我定義的結構如下:內存對齊和結構的大小

struct MyData { 
    int a; 
    char b; 
    int c; 
    byte d; 
    byte e; 
} 

我依稀記得讀取該結構的大小不僅取決於數據類型,而且內存對齊。在32位CPU上,MyData結構將是4個字節+ 1個字節+ 4個字節+ 1個字節+ 1個字節= 11個字節。這是我的問題,內存對齊增加了結構的大小:4字節+ 1字節(+3字節填充)+ 4字節+ 1字節(+3字節填充)+ 1字節(+3字節填充)= 20字節。

這是錯誤的嗎?我錯過了什麼嗎?這是語言特定的嗎?我可以打包結構嗎?如果是這樣,優點和缺點是什麼?

謝謝!

+1

一個小小的谷歌搜索和sizeof()測試可以給你很多的信息。你可能會在這裏找到一些有用的東西:http://c-faq.com/ – pzanoni 2012-04-12 21:41:42

回答

0

有之間和結構成員後未指定填充。沒有填充所述第一結構構件之前,也就是:

struct MyData bla; 

int val = (char *) &bla == (char *) &bla.a; // val is 1 

的指針結構(適當轉換)指向所述第一結構構件。

結構對象的大小考慮到填充和等於所述未指定填補處理的大小的成員+總和的大小的總和。

2

編譯器可以按照它認爲合適的方式填充結構。通常,最後兩個byte不會被填充分隔,因此大小將變爲4 (int) + 1 (char) + 3 (padding) + 4 (int) + 1 (byte) + 1 (byte) + 2 (padding) = 16

許多編譯器允許按照附註打包結構。這樣做的好處是減少了內存使用量,對於非對齊的int成員而言讀取速度較慢。

0

是的,編譯器會自然對齊與其大小相匹配的邊界上的類型。您可以使用編譯器編譯指示如

#pragma pack(1) 

您還可以通過重新排列你的聲明把你在整數後開始和單字節避免一些填充力量結構的包裝。

,您可以輕鬆打印sizeof(struct MyData)

1

測試這個你是不是錯了,說明內存對齊可以增加結構的大小;然而,關於內存如何對齊的猜測並不適用於所有平臺。這是嚴格平臺特定的。

基本上,大多數平臺傾向於在$ {WORDSIZE}對準,或者如果數據類型比$ {WORDSIZE}小,則它對準上的$ {WORDSIZE}

例如下一個可用的分數,如果你有一個32位的字,並且你正在存儲16位的短路信號,它們可能會在一個字的零和十六位之間對齊。但這不是保證,因爲它確實是平臺特定的。

調整您結構對於較小的廢物由於填充,命令由數據類型的元素,具有較大的數據類型的第一。這往往會允許將多個字節打包到同一個單詞中(如果可能的話),並且大於單詞條目將很好地終止在單詞邊界上,因爲它們傾向於是單詞的單倍數(四字,雙字,...)