C++11 中的动态对齐内存分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6973995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 21:03:50  来源:igfitidea点击:

Dynamic aligned memory allocation in C++11

c++c++11

提问by user882903

posix_memalignand _aligned_mallocon Windows allow to dynamically allocate an aligned chunk of memory. Is there anything similar in C++11? As far as I know, the alignaskeyword only works with statically allocated objects.

posix_memalign_aligned_malloc在Windows上允许动态分配的内存块对齐。C ++ 11中有类似的东西吗?据我所知,该alignas关键字仅适用于静态分配的对象。

回答by Michael Spencer

It depends on what alignment you require. For anything <= to alignof(std::max_align_t), newworks as per n3242 3.7.4.1/2:

这取决于您需要什么对齐方式。对于任何 <= to alignof(std::max_align_t)new按照 n3242 3.7.4.1/2 工作:

The pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type with a fundamental alignment requirement

返回的指针应适当对齐,以便它可以转换为具有基本对齐要求的任何完整对象类型的指针

std::max_align_tis a complete object type with the strictest fundamental alignment.

std::max_align_t是具有最严格基本对齐的完整对象类型。

Note that allocation of arrays of charor unsigned charbut not signed charhave a different rule in 5.3.4/10:

注意charor unsigned charbut not数组的分配signed char在 5.3.4/10 有不同的规则:

For arrays of char and unsigned char, the di?erence between the result of the new-expression and the address returned by the allocation function shall be an integral multiple of the strictest fundamental alignment requirement (3.11) of any object type whose size is no greater than the size of the array being created.

对于 char 和 unsigned char 数组,new 表达式的结果与分配函数返回的地址之间的差应是大小为 no 的任何对象类型的最严格的基本对齐要求 (3.11) 的整数倍大于正在创建的数组的大小。

So new char[1];can have an alignment of 1.

所以new char[1];可以有 1 的对齐。

As for allocating memory with an alignment greater than alignof(std::max_align_t), C++11 provides no direct way to do this. The only reliable way is to allocate at least size + alignmentbytes and use std::alignto get a correctly aligned location in this buffer.

至于分配对齐大于 的内存alignof(std::max_align_t),C++11 没有提供直接的方法来做到这一点。唯一可靠的方法是至少分配size + alignment字节并使用std::align在此缓冲区中获得正确对齐的位置。

This can waste a lot of memory, so if you need a lot of these, you could create an allocator that allocates a chunk large enough for all of them and use std::align on that. Your overhead is then amortized across all of the allocations.

这可能会浪费大量内存,因此如果您需要大量内存,您可以创建一个分配器,为所有这些分配足够大的块,并在其上使用 std::align 。然后,您的开销会在所有分配中摊销。

Your other option is to wait for http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3396.htmto make it into the standard.

您的另一个选择是等待http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3396.htm使其成为标准。

Personally I would just write an abstraction layer over the OS provided APIs for allocating aligned memory.

就我个人而言,我只会在操作系统提供的 API 上编写一个抽象层来分配对齐的内存。

回答by Hongli

You can use posix_memalign/_aligned_malloc to allocate a piece of memory and then using the special 'new' operator syntax to initialize an object in that memory region. Something like this:

您可以使用 posix_memalign/_aligned_malloc 分配一块内存,然后使用特殊的“new”运算符语法来初始化该内存区域中的对象。像这样的东西:

// Allocate raw memory for a Foo object.
void *mem;
size_t alignment = 0x1000;
size_t size = ?;
posix_memalign(&mem, alignment, size);
// Call the constructor on the allocated memory.
Foo *foo = new (mem) Foo(...);

// Now you have a useable object.
foo->some_method();

// Call destructor without freeing object memory.
foo->~Foo();
// Free raw memory.
free(foo);

回答by Taahir Ahmed

Take a look at std::aligned_storageand the alignas()operator. They're part of C++11, and seem to be exactly what you're looking for.

看看std::aligned_storagealignas()运营商。它们是 C++11 的一部分,似乎正是您正在寻找的。

回答by Armen Tsirunyan

C++03 and C++0x have operator new.

C++03 和 C++0x 有operator new.

new Tor new T[]guarantees to return properly aligned memory for object of type T.

new Tnew T[]保证为类型 T 的对象返回正确对齐的内存。

new char[], new signed char[]and new unsigned char[]guarantee to return memory properly aligned for anyobject, so that you can use placement new on it.

new char[]new signed char[]new unsigned char[]保证为任何对象返回正确对齐的内存,以便您可以在其上使用新的布局。

回答by Michal Fapso

For aligned memory allocated on heap I use align() implementation from http://code.google.com/p/c-plus/source/browse/src/util.h#57, because my gcc4.8 seems to not support it. Here is a sample code:

对于在堆上分配的对齐内存,我使用http://code.google.com/p/c-plus/source/browse/src/util.h#57 中的align() 实现,因为我的 gcc4.8 似乎不支持它。这是一个示例代码:

typedef float TItem;
static const int SIZE = 100;
static const int ALIGNMENT = 16;

// allocate heap storage larger then SIZE
TItem* storage = new TItem[SIZE + (ALIGNMENT / sizeof(TItem))];
void* storage_ptr = (void*)storage;
size_t storage_size = sizeof(TItem) * (SIZE + 1);
// aligned_array should be properly aligned
TItem* aligned_array = (TItem*) align(MEM_ALIGNMENT, sizeof(TItem) * SIZE, storage_ptr, storage_size);
if (!aligned_array) { throw std::bad_alloc(); }

回答by Jason

Intel's TBBprovides a portable cache_aligned_allocator, which I think you might be what you're looking for.

英特尔的TBB提供了一个便携式cache_aligned_allocator,我认为您可能正在寻找它。

回答by Puppy

The C++ Standard has always guaranteed suitable alignment for anyobject from heap allocations- that is,

C++ 标准始终保证堆分配中任何对象的合适对齐 -即,

template<typename T> T* func() {
    char* buf = new char[sizeof(T)];
    return new(buf) T();
}

is guaranteed not to fail for alignment reasons.

保证不会因对齐原因而失败。