我正在开发一个使用 Win32 的HeapAlloc的通用库
MSDN 没有提到 Win32 的 HeapAlloc 的对齐保证,但我确实需要知道它使用什么对齐,这样我才能避免过多的填充。
在我的机器(vista,x86)上,所有分配都以 8 个字节对齐。其他平台也是这样吗?
我正在开发一个使用 Win32 的HeapAlloc的通用库
MSDN 没有提到 Win32 的 HeapAlloc 的对齐保证,但我确实需要知道它使用什么对齐,这样我才能避免过多的填充。
在我的机器(vista,x86)上,所有分配都以 8 个字节对齐。其他平台也是这样吗?
令人惊讶的是,谷歌发现了并不总是符合 SSE 的证据:HeapAlloc
HeapAlloc() 使所有对象总是 8 字节对齐,无论它们的大小是多少(但不是 16 字节对齐,对于 SSE)。
该帖子来自 2008 年中期,表明最近的 Windows XP 存在此错误。
另请参阅http://support.microsoft.com/kb/286470:
Windows 堆管理器(所有版本)始终保证堆分配具有 8 字节对齐的起始地址(在 64 位平台上对齐为 16 字节)。
HeapAlloc 函数并没有在 MSDN 页面中指定对齐保证,但我倾向于认为它应该具有与 GlobalAlloc 相同的保证,即保证返回 8 字节对齐的内存(尽管依赖未记录的特性是邪恶的) ; 毕竟,它明确表示 Global/LocalAlloc 只是 HeapAlloc 的包装器(尽管它们可能会丢弃前n个字节以获得对齐的内存 - 但我认为这不太可能)。
如果您真的想确定,只需使用 GlobalAlloc,甚至是 VirtualAlloc,其粒度是页面粒度,通常为 4 KB (IIRC),但在这种情况下,对于小型分配,您将浪费大量内存。
顺便说一句,如果您使用 C++ new 运算符,则可以保证为您指定的类型正确对齐内存:这可能是要走的路。
Amd64 堆对齐记录在这里:
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
...堆栈指针和 malloc 或 alloca 内存,16 字节对齐以提高性能。
对齐方式将使得返回的地址可以转换为任何类型的指针。否则,您将无法在应用程序中使用内存。