2011-09-06 44 views
9

我正在尋找一個關於C++中的內存對齊,典型的方法,編譯器之間的差異和常見陷阱的好(全面)文檔。只是爲了檢查我對該主題的理解是否正確,並學習新的東西。我在哪裏可以找到跨不同平臺/編譯器的C++內存對齊方面的文檔?

這個問題由我的回答啓發,我用下面的結構另外一個問題:

char const buf[1000] = ...; 
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // shift can be anything 

它被批評爲不符合內存對齊規則。你能解釋爲什麼這種方法存在缺陷從內存對齊的角度來看,是否可以解釋爲什麼?一個不起作用的例子將受到高度讚賞。我知道這通常是一種不好的方法,但我經常在網絡協議實現中使用它,所以它比實際問題更具實際意義。

另請不要在這裏提到strict-aliasing,這是另一個問題。

+0

移位不是系統字長的倍數嗎?你可能因爲試圖在一個單詞的中間找到一個指針(比如在一個32位字的中間)而受到批評,這很奇怪。 –

+1

即使shift是4的倍數,也不能保證'buf'會在4的倍數地址處開始 – nos

+0

'shift'可以是任何東西,更新問題 –

回答

6

非堆分配數組char對它們的對齊沒有特定要求。所以你的一千個字符的緩衝區可能在一個奇怪的偏移量上。如果編譯器沒有將其分割爲單獨的讀取+位掩碼操作,則試圖從該偏移量中讀取int(重新解釋爲int指針顯而易見)會導致性能較差甚至在某些硬件上發生總線錯誤。

堆分配的數組char保證適當對齊以存儲任何對象類型,所以這總是一個選項。

對於基於非堆的存儲,請使用boost::aligned_storage,它確保空間正確對齊以供一般使用。

+0

+1:不幸的是我不能接受兩個答案,所以我應該接受另一個回答主要問題的答案 –

0

想象一下地址必須像16位字節對齊的情況,例如PS3。 然後想象一下這個轉換== 1. 這肯定是一個非16字節的對齊指針,它不適用於這臺機器。

相關問題