2013-03-17 91 views
1

我有這樣的結構在我的代碼:的sizeof給出意想不到的結果爲我的結構

struct BlockDescriptor 
{ 
    struct BlockDescriptor * pNext; 
    bool _isFree; 
}; 

和我傾向於相信它的大小是4 + 1 = 5(4用於指針和1bool) ,但由於某種原因,sizeof(struct BlockDescriptor)返回8!有人能告訴我爲什麼嗎?

是否因爲打包問題導致5四捨五入爲4的倍數(因爲大多數計算機最適合使用32位),並且是否有某種方法可以強制它使用真實大小(如果這樣其實真正的大小)?

+1

「pNext」和「_isFree」之間的填充。您可以通過編譯器特定的機制強制執行「打包」。 – cnicutar 2013-03-17 22:02:04

+0

在struct定義之前放置#pragma pack(1)。 – 2013-03-17 22:06:19

+0

爲什麼'sizeof(struct BlockDescriptor)'返回什麼對你很重要? – 2013-03-17 22:08:15

回答

1

默認情況下,struct的數據成員正在對齊。這些數據成員之間可能會有填充以及最後一個數據成員之後的填充。在你的情況下,填充最有可能在最後。

第一個數據成員是一個指針,在你的情況下需要4個字節的內存。然後,儘管另一個成員是隻需要1個字節的內存的char,但有一個填充爲4的倍數,但原因並不是因爲「32位是大多數計算機最適合的」正如你所說,但是因爲4是最大數據成員的大小。

通常有一個編譯指示允許您指定自定義對齊可用。在Visual Studio中,有#pragma pack,這可能會幫助你在這種情況下。只要確保你知道你在做什麼。儘管您會盡量減少內存使用量,但可能會對代碼的性能產生負面影響。

欲瞭解更多信息,看看相關的問題:
How to minimize the memory usage of a struct-type?
How does sizeof calculate the size of structures
Is the size of a struct required to be an exact multiple of the alignment of that struct?
甚至Determining the alignment of C/C++ structures in relation to its members

+0

是的,對齊由最大數據成員的大小定義我不相信我忘記了:P 如果我的編程教授看到我會得到一個徹底的衝擊:) – angryInsomniac 2013-03-17 22:26:41

0

發佈的回答禮貌:盧卡Rahne和cnicutar

有pNext和_isFree之間填充。您可以通過編譯器特定的機制強制「打包」,在結構體定義之前放置#pragma pack(1)

+1

在** _isFree之後,填充更可能是**,以將結構的大小填充到8個字節。 – 2013-03-17 22:20:47

+0

@PeteBecker yup,_isFree正在對齊到4,這是結構的對齊方式,因爲它的最大數據成員的大小爲4. – angryInsomniac 2013-03-17 22:28:09

0

當CPU訪問內存來獲取數據項(或結構成員),它實際上向存儲器控制器發送一個請求,該請求執行一些技巧使DRAM看起來是一個結構良好的數據存儲。實際上,DRAM是一堆細胞,每個細胞排列成N行(其中N可能是一千)。

瞭解大多數體系結構一次處理4,8,16或32位(或有時更大)的位,內存控制器針對4倍數地址的提取進行了優化。當您從地址abcd1002?那麼,內存控制器從地址abcd1000中取出四個字節,然後將它們移到以獲得第三個字節(記住,它是0,1然後是2),並給出你糟糕的非對齊字節。因此,從一個對齊的地址獲取總是比從一個不對齊的地址快。

意識到這個事實,編譯器通過填充數據結構積極優化速度,以便以易於記憶的方式進行佈局。

希望能夠提供有關此問題的重要計算機體系結構透視圖。我沒有看到任何當前回復中提到的這一點,因此我想增加0.02美元。

相關問題