C ++如何对齐数组分配? [英] How to do c++ aligned array allocation?

查看:263
本文介绍了C ++如何对齐数组分配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想修改数组分配:

 float * a = new float[n] ;

使用对齐的分配器。我倾向于尝试使用new和posix_memalign放置(或等效的新c ++ 11),但是看到,因为

to use an aligned allocator. I was inclined to try to use placement new and posix_memalign (or the new c++11 equivalent), but see that placement new with arrays is problematic with array allocations, because the compiler may need to have additional storage for count or other metadata.

我可能需要为计数或其他元数据添加额外的存储空间。

I tried:

int main()
{
   float * a = new alignas(16) float[3] ;

   a[2] = 0.0 ;

   return a[2] ;
}

但是编译器似乎表明alignas被忽略:

but the compiler seems to indicate that the alignas is ignored:

$ 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

使用alignas的正确方法似乎是在结构声明中声明具有alignas的结构,但这仅适用于固定大小。

It looks like the proper way to use alignas is in a structure declaration declare a structure with alignas, but that will only work with a fixed size.

还有一个aligned_storage模板,但我认为这也仅适用于固定大小。

There is also a aligned_storage template, but I think that will also only work with fixed sizes.

是否有任何标准的方法来进行对齐的数组分配,从而在所有元素上调用构造函数?

Is there any standard way to do an aligned array allocation that will invoke the constructor on all the elements?

推荐答案

就像其他人所说的,不需要支持过度对齐的类型。使用它之前,请检查您的编译器文档。

As other people said, overaligned types are not required to be supported. Check your compiler documentation before using it.

您可以尝试使用以下方法之一解决问题:

You can try to solve your problem using one of the following approaches:

1)总体排列数组(按(期望的匹配度/ sizeof元素)-1 )并使用 std :: align 。链接到 libstdc ++ 实现

1) Overallocate your array (by (desired aligment / sizeof element) - 1) and use std::align. A link to libstdc++ implementation.

2)声明一个包含数组的结构所需的匹配度/ sizeof元素元素,并按所需的匹配度对齐。如果使用此类结构的数组,它应该为您提供紧凑的内存表示形式,但是您将无法使用常规的数组表示法或指针算术(因为(a)未定义的行为,(b)在那里)

2) declare a struct containing array of desired aligment / sizeof element elements and aligned by desired aligment. It should give you compact representation in memory if you use array of such structs, but you will not be able to use normal array notation or pointer arithmetics (as it (a) undefined behaviour, (b) there is a small chance that they will not be placed as you want)

3)编写自己的对齐分配函数。注意,您可以添加自己的运算符 new delete 版本。

3) Write your own aligned allocation function. Notice that you can add your own versions of operator new and 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指针,将指针对齐到所需的大小并返回它。

You will need to allocate memory, reserve enough space to store original pointer (returned by malloc/whatever) or amount of bytes pointer was displaced, so subsequent delete will free corect pointer, align pointer to needed size and return it.

此处是答案和另一个,其中显示了如何对齐内存。

Here is an answer, and another one, which shows how to align memory.

请注意,这两个答案都使用实现定义的行为,即对转换为整数的指针进行按位算术并将其转换回去。唯一真正完全标准的方法是将内存转换为 char * 并在其值和下一个对齐地址之间增加差值。

Notice that both of these answers uses implementation-defined behaviour of doing bitwise arithmetic on pointers converted to integers and converting them back. The only really completely standard way would be to cast memory to char* and add difference between its value and next aligned address.

如果可以使用一些非标准的内存分配函数,也可以将它们包装到自定义运算符 new 中。

If you can use some nonstandard memory allocation functions, you can wrap them into custom operator new too.

这篇关于C ++如何对齐数组分配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆