Ond*_*nde 10 c c++ alignment heapalloc
我正在开发一个使用Win32的HeapAlloc的通用库
MSDN没有提到Win32的HeapAlloc的对齐保证,但我真的需要知道它使用的对齐方式,所以我可以避免过多的填充.
在我的机器上(vista,x86),所有分配都以8个字节对齐.这对其他平台也是如此吗?
出人意料的是,谷歌变成了证据,那HeapAlloc并不总是SSE兼容:
HeapAlloc()使所有对象始终以8字节对齐,无论它们的大小如何(但对于SSE而言不是16字节对齐).
该帖子是从2008年中期开始的,表明最近的Windows XP遭受了这个漏洞.
另请参见http://support.microsoft.com/kb/286470:
Windows堆管理器(所有版本)始终保证堆分配具有8字节对齐的起始地址(在64位平台上,对齐为16字节).
HeapAlloc函数没有在MSDN页面中指定对齐保证,但我倾向于认为它应该具有与GlobalAlloc相同的保证,保证返回8字节对齐的内存(尽管依赖未记录的功能是邪恶的) ; 毕竟,明确表示 Global/LocalAlloc 只是 HeapAlloc 的包装器(尽管它们可能会丢弃前n 个字节以获取对齐的内存 - 但我认为这不太可能)。
文档页面同时更新,现在给出了精确的指示:
返回的内存对齐方式
HeapAlloc在MEMORY_ALLOCATION_ALIGNMENTWinNT.h 中:Run Code Online (Sandbox Code Playgroud)#if defined(_WIN64) || defined(_M_ALPHA) #define MEMORY_ALLOCATION_ALIGNMENT 16 #else #define MEMORY_ALLOCATION_ALIGNMENT 8 #endif
因此,在 64 位 Windows 上它是 16 个字节,在 32 位 Windows 上是 8 个字节,至少在文档引用的操作系统版本上(Windows XP 及以上)是这样。
如果你真的想确定的话,只需在特定情况下,您还可以使用GlobalAlloc,甚至VirtualAlloc,其粒度是页粒度,通常为 4 KB (IIRC),但在这种情况下,对于小分配,您将浪费大量内存。
顺便说一句,如果你使用 C++ new 运算符,您可以保证为您指定的类型正确对齐内存:这可能是正确的方法。这也不是真正正确的;在 C++17 之前,new没有必要的管道来处理“过度对齐”类型(即对齐要求大于 的类型std::max_align_t,通常是double),因此实际上通常只提供 8 或 16 字节对齐。从 C++17 开始,这个问题就得到了修复,new标准库中提供的 应该能够处理此类类型。有关更多信息,请参阅P0035R4、std::max_align_t、std::align_val_t。
| 归档时间: |
|
| 查看次数: |
4518 次 |
| 最近记录: |