对齐说明符是否适用于"新"?
Does the alignas specifier work with 'new'?
我的问题很简单;
对齐说明符是否与'new'一起工作?也就是说,如果一个结构体被定义为对齐,那么在分配new时它会对齐吗?
在c++ 17之前,如果你的类型的对齐方式没有过度对齐,那么是的,默认的new
将工作。"Over-aligned"表示您在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增加了一些内存分配器,这些分配器被赋予了所使用类型的对齐方式。这些分配器专门用于过度对齐类型(或者更具体地说,新扩展的过度对齐类型)。所以new pair<over_aligned, int>()
将在c++ 17中工作。
当然,这只适用于分配器处理过对齐类型的情况。
不,它没有。结构体将被填充到请求的对齐方式,但它不会被对齐。然而,这有可能在c++ 17中被允许(这个c++ 17提案存在的事实应该很好地证明了这在c++ 11中不能工作)。
我已经看到这似乎与一些内存分配器工作,但那纯粹是运气。例如,一些内存分配器会将它们的内存分配对齐到请求大小的2次方(最多4KB),作为对分配器的优化(减少内存碎片,可能更容易重用以前释放的内存,等等……)。但是,我测试的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;
}
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 选择排序C++(已修改)并非适用于所有情况
- 无法让"std::enable_if"适用于无作用域枚举
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 确定夏令时是否适用于特定日期
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- QT 样式表主题,适用于使用属性选择器的整个应用程序
- C++带有适用于左值和右值的引用参数的函数
- 代码适用于调试,但不适用于发布
- C++17 和更新的 std::分配器是否适用于动态数量的自定义堆?
- 适用于大型数组的无复制线程安全环形缓冲区
- NRVO 是否也适用于协程?
- 约束包容是否仅适用于概念?
- 程序只适用于包含(无副作用)cout声明
- 适用于频繁更改的大型数据集的最佳数据结构
- 相同的 for 循环适用于其他项目,但不适用于此项目。为什么?
- 无法让 FastNoise 适用于草地
- 其中列 = 值,仅适用于整数值