posix_memalign
和_aligned_malloc
允许动态分配对齐的内存块。 C ++ 11中有类似的东西吗?据我所知,alignas
关键字仅适用于静态分配的对象。
答案 0 :(得分:28)
这取决于您需要的对齐方式。对于< =到alignof(std::max_align_t)
的任何内容,new
按照n3242 3.7.4.1/2工作:
返回的指针应适当对齐,以便它可以 转换为具有基础的任何完整对象类型的指针 对齐要求
std::max_align_t
是一个完整的对象类型,具有最严格的基本对齐。
请注意,char
或unsigned char
但不是signed char
的数组分配在5.3.4 / 10中有不同的规则:
对于char和unsigned char的数组,结果之间的差异 new-expression和分配返回的地址 功能应是最严格基础的整数倍 大小为no的任何对象类型的对齐要求(3.11) 大于正在创建的数组的大小。
因此new char[1];
的对齐方式为1。
对于分配大于alignof(std::max_align_t)
的对齐的内存,C ++ 11没有提供直接的方法来执行此操作。唯一可靠的方法是至少分配size + alignment
个字节并使用std::align在此缓冲区中获得正确对齐的位置。
这可能会浪费大量内存,因此如果您需要大量内存,可以创建一个分配器,为所有这些分配一个足够大的块,并使用std :: align。然后,您的管理费用将在所有分配中摊销。
您的另一个选择是等待http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3396.htm使其成为标准。
就个人而言,我只想在操作系统提供的API上编写一个抽象层来分配对齐的内存。
答案 1 :(得分:9)
您可以使用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);
答案 2 :(得分:5)
C ++ 03和C ++ 0x有operator new
。
new T
或new T[]
保证为类型为T的对象返回正确对齐的内存。
new char[]
,new signed char[]
和new unsigned char[]
保证为 任何 对象返回正确对齐的内存,以便您可以使用展示位置新的。
答案 3 :(得分:5)
查看std::aligned_storage
和alignas()
运算符。它们是C ++ 11的一部分,似乎正是您正在寻找的。 p>
答案 4 :(得分:1)
对于在堆上分配的对齐内存,我使用来自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(); }
答案 5 :(得分:0)
英特尔TBB提供便携式cache_aligned_allocator
,我认为您可能正在寻找它。
答案 6 :(得分:-1)
C ++标准始终保证从堆分配中任何对象的适当对齐 - 即
template<typename T> T* func() {
char* buf = new char[sizeof(T)];
return new(buf) T();
}
保证不会因对齐原因而失败。