我想修改数组分配:
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] ;
}
但编译器似乎表明 alignas 被忽略了:
$ 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 的正确方法是在 structure declaration declare a structure with alignas 中,但这仅适用于固定尺寸。
还有一个 aligned_storage 模板,但我认为它也只适用于固定尺寸。
是否有任何标准的方法来进行对齐数组分配,从而在所有元素上调用构造函数?
最佳答案
正如其他人所说,不需要支持过度对齐的类型。在使用之前检查您的编译器文档。
您可以尝试使用以下方法之一解决您的问题:
1) 过度分配您的数组(通过 (desired aligment/sizeof element) - 1
)并使用 std::align . libstdc++
implementation 的链接.
2) 声明一个包含 desired aligment/sizeof element
元素数组并按所需对齐方式对齐的结构。如果您使用此类结构的数组,它应该在内存中为您提供紧凑的表示,但您将无法使用正常的数组表示法或指针算法(因为它 (a) 未定义的行为,(b) 那里有很小的机会它们不会按照您的意愿放置)
3) 编写自己的对齐分配函数。请注意,您可以添加自己的运算符 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
中。
关于c++ - 如何进行 C++ 对齐数组分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35832358/