我的问题很简单;
alignas 说明符是否与“新”一起使用?也就是说,如果一个struct被定义为对齐的,那么分配new时是否会对齐?
我的问题很简单;
alignas 说明符是否与“新”一起使用?也就是说,如果一个struct被定义为对齐的,那么分配new时是否会对齐?
在 C++17 之前,如果您的类型的对齐方式没有过度对齐,那么是的,默认值new
将起作用。“过度对齐”表示您在 中指定的对齐方式alignas
大于alignof(std::max_align_t)
。默认值new
将或多或少地与非过度对齐的类型一起使用;默认内存分配器将始终分配对齐等于alignof(std::max_align_t)
.
但是,如果您的类型的对齐方式过度对齐,那么您就不走运了。default 和您编写的new
任何全局new
运算符都无法知道类型所需的对齐方式,更不用说分配适合它的内存了。帮助这种情况的唯一方法是重载类的operator new
,这将能够查询类与 的对齐alignof
。
当然,如果该类被用作另一个类的成员,这将没有用。除非其他类也重载operator new
。所以简单的事情是new pair<over_aligned, int>()
行不通的。
C++17添加了许多内存分配器,这些分配器被赋予了正在使用的类型的对齐方式。这些分配器专门用于过度对齐的类型(或者更具体地说,新扩展的过度对齐类型)。所以new pair<over_aligned, int>()
将在 C++17 中工作。
当然,这只适用于分配器处理过度对齐的类型。
不,不是的。该结构将被填充到请求的对齐位置,但不会对齐。然而,这有可能在 C++17 中被允许(这个 C++17 提案存在的事实应该很好地证明这在 C++11 中是行不通的)。
我已经看到这似乎适用于一些内存分配器,但这纯粹是运气。例如,一些内存分配器会将其内存分配与请求大小的 2 次方(最大 4KB)对齐,作为分配器的优化(减少内存碎片,可能更容易重用以前释放的内存等...) . 但是,我测试的 OS X 10.7 和 CentOS 6 系统中包含的 new/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;
}