我想修改一个数组分配:
float * a = new float[n] ;要使用对齐分配器,请执行以下操作。我倾向于尝试使用placement new和posix_memalign (或新的c++11等效项),但是看到了placement new with arrays is problematic with array allocations,因为compiler may need to have additional storage for count or other metadata。
我试过了:
int main()
{
float * a = new alignas(16) float[3] ;
a[2] = 0.0 ;
return a[2] ;
}但是编译器似乎表明对齐被忽略了:
$ g++ -std=c++11 t.cc -Werror
t.cc: In function ‘int main()’:
t.cc:4:39: error: attribute ignored [-Werror=attributes]
float * a = new alignas(16) float[3] ;
^
t.cc:4:39: note: an attribute that appertains to a type-specifier is ignored看起来正确的方式是在structure declaration declare a structure with alignas中使用对齐,但这只适用于固定大小。
还有一个aligned_storage模板,但我认为它也只适用于固定大小。
有没有什么标准的方法来做一个对齐的数组分配来调用所有元素上的构造函数?
发布于 2016-03-07 05:03:42
正如其他人所说,不需要支持过度对齐类型。在使用之前,请检查您的编译器文档。
您可以尝试使用以下方法之一来解决问题:
1)过度分配数组(通过(desired aligment / sizeof element) - 1)并使用std::align。指向libstdc++ implementation的链接。
2)声明一个包含desired aligment / sizeof element元素数组的结构,并通过所需的对齐方式对齐。如果你使用这种结构的数组,它应该在内存中给出紧凑的表示,但你将不能使用普通的数组符号或指针算法(因为它(a)未定义的行为,(b)有很小的可能性它们不会按你想要的那样放置)
3)编写自己的对齐分配函数。请注意,您可以添加自己版本的operator new和delete。
namespace my
{
struct aligned_allocator_tag {};
aligned_allocator_tag aligned;
}
void* operator new( std::size_t count, my::aligned_allocator_tag, std::size_t aligment);
void* operator new[]( std::size_t count, my::aligned_allocator_tag, std::size_t aligment)
{
return ::operator new(count, my::aligned, aligment);
}
//Usage
foo* c = new(my::aligned, 16) foo[20];您将需要分配内存,保留足够的空间来存储原始指针(由malloc返回)或指针被移位的字节数,因此后续的删除将释放corect指针,将指针对齐到所需的大小并返回它。
下面是an answer,and another one,它展示了如何对齐内存。
请注意,这两个答案都使用实现定义的行为,即对转换为整数的指针进行逐位运算,然后再将其转换回来。唯一真正完全标准的方法是将内存强制转换为char*,并将其值与下一个对齐地址相加。
如果可以使用一些非标准内存分配函数,也可以将它们封装到自定义操作符new中。
发布于 2016-03-07 04:56:54
基本上,你被卡住是因为,在expr.new中
是否支持过度对齐类型由实现定义。
有一个proposal可以更好地支持这一点。在此之前,如果你想做你想做的事情,你将不得不使用aligned_alloc而不是new。
如果你把你的数组放在一个结构中:
struct S {
alignas(16) float _[3];
};然后,new S将为您提供针对_的正确对齐,尽管不一定针对S本身。这可能就足够了。如果没有,那么您可以重载S本身上的operator new()和operator delete(),以保证正确的行为。
发布于 2016-03-07 05:12:58
在C++中对对齐的本地支持仍然令人沮丧。从外观上看,您正在对齐到一个4浮点向量,所以您错过了C++14不能比16字节对齐更好的危险,但即便如此,它也不是所有C++14编译器都可靠支持的特性。如果你需要使用new float[]的可移植代码,你已经输掉了这场竞赛。
我认为,在当前的标准中,你能得到的最接近的方法是创建一个向量大小和向量对齐的数据类型(例如,使用std::aligned_storage),然后养成使用该类型,而不是单个浮点数组来进行向量数学计算的习惯。如果你需要可变长度的向量,那么你必须四舍五入到最近的4个浮点数。
(抱歉,这不是您想要的答案,但我认为这是您继续前进所需的答案。)
https://stackoverflow.com/questions/35832358
复制相似问题