C ++ 11中的动态对齐内存分配

时间:2011-08-07 16:18:49

标签: c++ c++11

Windows上的

posix_memalign_aligned_malloc允许动态分配对齐的内存块。 C ++ 11中有类似的东西吗?据我所知,alignas关键字仅适用于静态分配的对象。

7 个答案:

答案 0 :(得分:28)

这取决于您需要的对齐方式。对于< =到alignof(std::max_align_t)的任何内容,new按照n3242 3.7.4.1/2工作:

  

返回的指针应适当对齐,以便它可以   转换为具有基础的任何完整对象类型的指针   对齐要求

std::max_align_t是一个完整的对象类型,具有最严格的基本对齐。

请注意,charunsigned 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 Tnew T[]保证为类型为T的对象返回正确对齐的内存。

new char[]new signed char[]new unsigned char[]保证为 任何 对象返回正确对齐的内存,以便您可以使用展示位置新的。

答案 3 :(得分:5)

查看std::aligned_storagealignas()运算符。它们是C ++ 11的一部分,似乎正是您正在寻找的。

答案 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();
}
保证

不会因对齐原因而失败。