是否与“新”的alignas符的工作?(Does the alignas specifier wor

2019-07-22 01:14发布

我的问题是相当简单的;

是否与“新”的alignas符的工作? 也就是说,如果一个结构被定义为排列,当有新的分配将它对准?

Answer 1:

如果你的类型的定位还没有结束对齐,然后是,默认的new会工作。 “在对齐”意味着你在指定对齐alignas大于alignof(std::max_align_t) 默认new将与非过对齐类型的意外或多或少工作; 默认内存分配器将始终有对准等于分配内存alignof(std::max_align_t)

如果你的类型的对齐然而,过度对齐,你的运气了出来。 无论是默认的new ,也没有任何全球new你写的操作,就能知道该类型所需的排列,更别说分配适当的内存给它。 以帮助这种情况下,唯一的办法是重载类的operator new ,这将能够查询类的对齐alignof

当然,如果该类被用作另一个类的构件,这将不会是有用的。 除非没有其他类还重载operator new 。 这样简单的东西new pair<over_aligned, int>()将无法工作。

一种用于C ++ 17(已接受)提议增加了支持用于过对准类型的动态分配 ,通过具有的过载operator new/delete该取alignof被分配的类型。 这也将支持小于最大取向型路线,让您的内存分配器不必总是返回内存对齐alignof(std::max_align_t)

话虽这么说,编译器不需要支持通过对齐类型的。



Answer 2:

不,不是的。 该结构将被填充到所要求的调整,但不会对齐。 有机会的话,但是,这将允许在C ++ 17 (这个C ++ 17的提案存在应该是不错的证明这不能工作在C ++ 11的事实)。

我已经看到了这出现了一些内存分配工作,但这是纯粹的运气。 例如,一些内存分配器将调整其内存分配的请求的大小(高达4KB)作为优化的2权力的分配(减少内存碎片,可能更容易重用以前释放的内存,等...) 。 然而,包括在我测试不这样做并不能用下面的代码的OS X 10.7和CentOS 6系统中的新/ malloc实现:

#include <stdlib.h>
#include <assert.h>

struct alignas(8)   test_struct_8   { char data; };
struct alignas(16)  test_struct_16  { char data; };
struct alignas(32)  test_struct_32  { char data; };
struct alignas(64)  test_struct_64  { char data; };
struct alignas(128) test_struct_128 { char data; };
struct alignas(256) test_struct_256 { char data; };
struct alignas(512) test_struct_512 { char data; };

int main() {
   test_struct_8   *heap_8   = new test_struct_8;
   test_struct_16  *heap_16  = new test_struct_16;
   test_struct_32  *heap_32  = new test_struct_32;
   test_struct_64  *heap_64  = new test_struct_64;
   test_struct_128 *heap_128 = new test_struct_128;
   test_struct_256 *heap_256 = new test_struct_256;
   test_struct_512 *heap_512 = new test_struct_512;

#define IS_ALIGNED(addr,size)   ((((size_t)(addr)) % (size)) == 0)

   assert(IS_ALIGNED(heap_8, 8));
   assert(IS_ALIGNED(heap_16, 16));
   assert(IS_ALIGNED(heap_32, 32));
   assert(IS_ALIGNED(heap_64, 64));
   assert(IS_ALIGNED(heap_128, 128));
   assert(IS_ALIGNED(heap_256, 256));
   assert(IS_ALIGNED(heap_512, 512));

   delete heap_8;
   delete heap_16;
   delete heap_32;
   delete heap_64;
   delete heap_128;
   delete heap_256;
   delete heap_512;

return 0;
}


文章来源: Does the alignas specifier work with 'new'?