dynamicalignment的内存分配在C + + 11
Windows上的posix_memalign
和_aligned_malloc
允许dynamic分配alignment的内存块。 在C ++ 11中有没有类似的东西? 据我所知, alignas
关键字只适用于静态分配的对象。
这取决于你需要什么路线。 对于<=来alignof(std::max_align_t)
任何东西,根据n3242 3.7.4.1/2:
返回的指针应适当alignment,以便可将其转换为具有基本alignment要求的任何完整对象types的指针
std::max_align_t
是具有最严格基本alignment的完整对象types。
请注意, char
或unsigned char
数组的分配但不包含signed char
在5.3.4 / 10中有不同的规则:
对于char和unsigned char数组,新expression式的结果与分配函数返回的地址之间的差异应该是大小不大于任何对象types的最严格的基本alignment要求(3.11)的整数倍正在创build的数组的大小。
所以new char[1];
可以有一个1的alignment。
至于分配大于alignof(std::max_align_t)
的alignment方式的内存,C ++ 11没有提供直接的方法来做到这一点。 唯一可靠的方法是至less分配size + alignment
字节,并使用std :: align在此缓冲区中获得正确alignment的位置。
这可能浪费很多内存,所以如果你需要很多内存的话,你可以创build一个分配器来分配足够大的内存块,并使用std :: align。 您的开销随后在所有分配中摊销。
您的其他select是等待http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3396.htm将其纳入标准。;
就我个人而言,我只是写在OS提供的API分配alignment内存的抽象层。
你可以使用posix_memalign / _aligned_malloc来分配一块内存,然后使用特殊的'new'操作符语法来初始化该内存区域中的一个对象。 像这样的东西:
// Allocate raw memory for a Foo object. void *mem; size_t alignment = 0x1000; size_t size = ?; posix_memalign(&mem, alignment, size); // Call the constructor on the allocated memory. Foo *foo = new (mem) Foo(...); // Now you have a useable object. foo->some_method(); // Call destructor without freeing object memory. foo->~Foo(); // Free raw memory. free(foo);
C ++ 03和C ++ 0x有operator new
。
new T
或new T[]
保证为typesT的对象返回正确alignment的内存。
new char[]
, new signed char[]
和new unsigned char[]
保证返回内存正确alignment任何对象,以便您可以使用新的位置。
看看std::aligned_storage
和alignas()
运算符。 它们是C ++ 11的一部分,看起来正是你正在寻找的东西。
对于分配在堆上的alignment内存,我使用http://code.google.com/p/c-plus/source/browse/src/util.h#57中的; align()实现,因为我的gcc4.8似乎不支持它。 这是一个示例代码:
typedef float TItem; static const int SIZE = 100; static const int ALIGNMENT = 16; // allocate heap storage larger then SIZE TItem* storage = new TItem[SIZE + (ALIGNMENT / sizeof(TItem))]; void* storage_ptr = (void*)storage; size_t storage_size = sizeof(TItem) * (SIZE + 1); // aligned_array should be properly aligned TItem* aligned_array = (TItem*) align(MEM_ALIGNMENT, sizeof(TItem) * SIZE, storage_ptr, storage_size); if (!aligned_array) { throw std::bad_alloc(); }
英特尔的TBB提供了一个可移植的cache_aligned_allocator
,我想你可能是你在找什么。
C ++标准始终保证从堆分配中对任何对象进行合适的alignment – 也就是说,
template<typename T> T* func() { char* buf = new char[sizeof(T)]; return new(buf) T(); }
保证不因alignment原因失败。