C++ 如何强制新运算符返回的指针与32字节对齐

C++ 如何强制新运算符返回的指针与32字节对齐,c++,new-operator,avx2,C++,New Operator,Avx2,我在程序中使用AVX2内在函数,并在其中一个类中声明一个_m256i变量,如下所示: class A { protected: __m256i buffer; public: A() { buffer = _mm256_setzero_si256(); } }; 当我创建一个实例时,如果缓冲区的内存位置不是32字节对齐的,我得到了一个Seg错误。有没有办法强制新运算符的返回地址或缓冲区的内存地址32字节对齐?您可以尝试对齐说明符 参见C++标准的7.7

我在程序中使用AVX2内在函数,并在其中一个类中声明一个_m256i变量,如下所示:

class A {
protected:
    __m256i buffer;
public:
    A() { 
        buffer = _mm256_setzero_si256();
    }
};
当我创建一个实例时,如果缓冲区的内存位置不是32字节对齐的,我得到了一个Seg错误。有没有办法强制新运算符的返回地址或缓冲区的内存地址32字节对齐?

您可以尝试对齐说明符


参见C++标准的7.7.2。基于注释,< <代码> > Alcasas说明符似乎不起作用:

大多数编译器都有内置的对齐分配函数,如GCC。此功能可以与placement
new
操作符结合使用,以创建对齐的对象实例

例如:

void* ptr = aligned_alloc(32, sizeof(A));
A* a = new(ptr) A;

注意:使用placement
new
需要手动调用析构函数,使用
delete
不起作用

我认为您不需要placement new:

#包括
#包括
使用size\u t=::std::size\u t;
模板
结构对齐为(对齐)对齐新建{
静态_断言(对齐>0,“对齐必须为正”);
静态断言((对齐和(对齐-1))==0,
“对齐必须是2的幂”);
静态断言((对齐%sizeof(void*))==0,
“对齐必须是sizeof(void*)”的倍数;
静态void*运算符new(size_t count){return Allocate(count);}
静态void*运算符new[](size_t count){return Allocate(count);}
静态void操作符delete(void*ptr){free(ptr);}
静态void操作符delete[](void*ptr){free(ptr);}
私人:
静态无效*分配(大小\u t计数){
void*result=nullptr;
const auto alloc_failed=posix_memalign(&result,ALIGNMENT,count);
如果(alloc_失败)抛出::std::bad_alloc();
返回结果;
}
};
现在只需从
AlignedNew
继承即可


另请参见此方案,该方案已被C++17接受:.

使用和分配器,如示例中所示?或者,您的编译器可能具有内置的对齐分配函数,如GCC。-然后您需要将
new
放入对齐的StorageThank@UnholySheep。在我弄明白为什么alignas不能与G++一起工作之前,我暂时使用aligned_alloc+placement new。如果你能将其作为答案发布,我会将其标记为已接受。不幸的是,“class alignas(32)A”和“\uuuu m256i alignas(32)buffer”都不会对g++版本5.4.0 20160609、Ubuntu 16.04产生任何影响。我尝试了这两种方法,结果内存地址仍然只对齐16个字节。@Harper编译时是否使用了
-std=c++11
命令行选项?我相信这不适用于动态(
new
ed)内存分配:我需要使用-std=gnu++11而不是c++11
:35:13:警告:属性已忽略[-Wattributes]_uum256i alignas(32)缓冲区;^~~~~~~:35:13:注意:与类型说明符相关的属性被忽略
我认为重载new操作符的方法更优雅,因为它不需要调用方知道关于类的任何细节。谢谢
void* ptr = aligned_alloc(32, sizeof(A));
A* a = new(ptr) A;