10

我正在开发一个使用 Win32 的HeapAlloc的通用库

MSDN 没有提到 Win32 的 HeapAlloc 的对齐保证,但我确实需要知道它使用什么对齐,这样我才能避免过多的填充。

在我的机器(vista,x86)上,所有分配都以 8 个字节对齐。其他平台也是这样吗?

4

4 回答 4

6

令人惊讶的是,谷歌发现了并不总是符合 SSE 的证据:HeapAlloc

HeapAlloc() 使所有对象总是 8 字节对齐,无论它们的大小是多少(但不是 16 字节对齐,对于 SSE)。

该帖子来自 2008 年中期,表明最近的 Windows XP 存在此错误。

另请参阅http://support.microsoft.com/kb/286470

Windows 堆管理器(所有版本)始终保证堆分配具有 8 字节对齐的起始地址(在 64 位平台上对齐为 16 字节)。

于 2010-05-10T20:41:02.887 回答
2

HeapAlloc 函数并没有在 MSDN 页面中指定对齐保证,但我倾向于认为它应该具有与 GlobalAlloc 相同的保证,即保证返回 8 字节对齐的内存(尽管依赖未记录的特性是邪恶的) ; 毕竟,它明确表示 Global/LocalAlloc 只是 HeapAlloc 的包装器(尽管它们可能会丢弃前n个字节以获得对齐的内存 - 但我认为这不太可能)。

如果您真的想确定,只需使用 GlobalAlloc,甚至是 VirtualAlloc,其粒度是页面粒度,通常为 4 KB (IIRC),但在这种情况下,对于小型分配,您将浪费大量内存。

顺便说一句,如果您使用 C++ new 运算符,则可以保证为您指定的类型正确对齐内存:这可能是要走的路。

于 2010-05-10T20:52:10.510 回答
1

Amd64 堆对齐记录在这里:

https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160

...堆栈指针和 malloc 或 alloca 内存,16 字节对齐以提高性能。

于 2021-07-13T19:25:12.650 回答
0

对齐方式将使得返回的地址可以转换为任何类型的指针。否则,您将无法在应用程序中使用内存。

于 2010-05-10T20:08:58.240 回答