我的问题是相当简单的;
是否与“新”的alignas符的工作? 也就是说,如果一个结构被定义为排列,当有新的分配将它对准?
我的问题是相当简单的;
是否与“新”的alignas符的工作? 也就是说,如果一个结构被定义为排列,当有新的分配将它对准?
如果你的类型的定位还没有结束对齐,然后是,默认的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)
话虽这么说,编译器不需要支持通过对齐类型的。
不,不是的。 该结构将被填充到所要求的调整,但不会对齐。 有机会的话,但是,这将允许在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;
}