2010-05-10 40 views
7

我正在開發它採用了通用庫的Win32的HeapAlloc不HeapAlloc使用什麼樣的定位

MSDN沒有提及對準保證爲Win32的HeapAlloc,但我真的需要知道的比對可以使用的,所以我能避免過多的填充。

在我的機器上(vista,x86),所有的分配對齊在8個字節。這對其他平臺也是如此嗎?

+6

如果MSDN不說,那麼*沒有保證*。即使你問了1000個人,他們都確定他們的機器上有8個字節,但這不是保證,你可能不應該依賴它。 – 2010-05-10 19:56:02

+0

我同意上述說法。您可能需要查看http://blogs.msdn.com/oldnewthing/archive/2007/12/27/6873648.aspx,看看它是否與其相關。 – torak 2010-05-10 20:01:48

+1

我同意,沒有保證,但我不是在這裏要求保證:我在尋求經驗。 我相信微軟永遠不會降低8字節以下的對齊,因爲double將不會被讀取。我只想知道這對於嵌入式平臺也是如此。 – Ondergetekende 2010-05-17 07:41:09

回答

2

HeapAlloc函數沒有在MSDN頁面中指定對齊保證,但我傾向於認爲它應該具有與GlobalAlloc相同的保證,它保證返回內存8字節對齊(儘管依賴在無證的功能是邪惡的);畢竟,它明確表示Global/LocalAlloc只是HeapAlloc的封裝(儘管它們可能會丟棄第一個字節來獲得對齊的內存 - 但我認爲這不太可能)。

如果您確實想要確定,只需使用GlobalAlloc,甚至VirtualAlloc,其粒度就是頁面粒度,通常是4 KB(IIRC),但在這種情況下,對於小分配,您將浪費很多記憶。順便說一句,如果您使用C++ new運算符,則可以保證爲您指定的類型正確地對內存進行對齊:這可能是一條可行的路。

1

對齊方式將返回的地址可以轉換爲任何類型的指針。否則,您將無法在應用程序中使用內存。

+0

如果我正確理解你的答案,返回的地址可以被轉換爲任何類型的指針的事實與分配的內存的對齊無關。 – 2010-05-10 20:46:29

+0

@Matteo:它是相關的。如果它沒有對齊類型T,那麼對'T *'進行轉換將是無效的(它會進行編譯,但不能保證工作)。因爲它可以轉換成任何類型,所以它必須嚴格對齊以適應任何類型。 – jalf 2010-05-10 21:34:48

+0

好吧,我用另一種方式理解你的答案,所以我之前說過的話不適用;仍然,操作系統不能保證它對齊*任何*類型,否則只有一個NULL指針會好的:)。可能保證爲最大類型工作,這需要與編寫分配器的人員知道對齊(或者編寫分配器的人願意直接支持的最大類型)。 – 2010-05-10 21:41:30

3

出人意料的是,谷歌變成了evidenceHeapAlloc並不總是SSE兼容:

HeapAlloc()的所有對象總是8字節對齊,不管它們的大小是多少(而不是16個字節對於SSE)。

這篇文章是從2008年中期開始的,這表明最近的Windows XP受此漏洞影響。

http://support.microsoft.com/kb/286470參見:

Windows堆管理器(所有版本)始終保證堆分配具有對齊(在64位平臺上的定位是8個字節的起始地址16-字節)。

+0

是的,SSE類型生活在一種影子存在的地方,它們的排列很少受到分配函數的重視。我不確定爲什麼,但Windows和Linux似乎都是這種情況。默認情況下,你不會得到比8字節更好的對齊保證。 – jalf 2010-05-10 21:38:30

+0

@jalf:奇怪!我記得在1999年AltiVec被引入時,蘋果公司立即重新分配了它們的分配函數「NewPtr」和「NewHandle」,以便16字節對齊。這不像你打破舊軟件的方式! – Potatoswatter 2010-05-10 21:44:59