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

use*_*903 39 c++ c++11

posix_memalign并且_aligned_malloc在Windows上允许动态分配对齐的内存块.C++ 11中有类似的东西吗?据我所知,该alignas关键字仅适用于静态分配的对象.

Mic*_*cer 30

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

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

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

请注意,在5.3.4/10 中分配charunsigned charsigned char具有不同规则的数组:

对于char和unsigned char的数组,new-expression的结果与分配函数返回的地址之间的差异应该是任何对象类型的最严格的基本对齐要求(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上编写一个抽象层来分配对齐的内存.


Hon*_*gli 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);
Run Code Online (Sandbox Code Playgroud)

  • malloc不支持*对齐任意大小*,这是user882903可能想要的. (4认同)

Arm*_*yan 5

C++ 03和C++ 0x都有operator new.

new Tnew T[]保证为类型为T的对象返回正确对齐的内存

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

  • 这些不适用于"任何"对象.比如说,一个必须在页面边界分配的对象:当然,没有C++实现将所有分配与4096字节边界对齐.它保证支持任何标准C++原语类型(double通常是限制性最强的类型),但PC上的大多数编译器/运行时都无法支持对齐SSE类型(16字节对齐)的对齐要求.操作员new不对其所使用的类型进行对齐(或实际上是任何元数据)这一事实是该语言的一个巨大缺陷. (15认同)
  • 标准实际上所说的是"任何具有基本对齐要求的对象类型",它肯定不能满足*ANY*对象. (3认同)

小智 5

看一下std::aligned_storagealignas()运算符。它们是C ++ 11的一部分,似乎正是您想要的。


Pup*_*ppy -1

C++ 标准始终保证堆分配中的任何对象的适当对齐 - 也就是说,

template<typename T> T* func() {
    char* buf = new char[sizeof(T)];
    return new(buf) T();
}
Run Code Online (Sandbox Code Playgroud)

保证不会因对齐原因而失败。

  • 这个答案是错误的,分配函数只支持对齐要求不比“alignof(std::max_align_t)”更严格的对象。参见 3.7.4.1p2(或 5.3.4p10)和 3.11p2。也就是说,对象必须具有“基本对齐”。 (12认同)
  • 抱歉,我认为我的问题不够精确。我想明确指定边界,就像 posix_memalign 的情况一样。询问的原因是我想在不同的缓存行分配小对象以避免错误共享。 (4认同)