在 C++ 中为过度对齐类型获取适当对齐的堆存储

问题描述 投票:0回答:1

在某些用例中,您需要先分配存储空间,然后再在此存储中创建对象。
然后为了创建这些对象,您可能需要使用placement new:

T *pobj = new(pstorage);

但是您必须提供正确对齐的

pstorage

AFAIU 以下代码不提供过度对齐类型的保证。

// properly aligned heap storage to hold N contiguous T objects
unsigned char *storage = new unsigned char[N*sizeof(T)];

operator new
过度对齐类型的重载似乎无法明确使用(https://stackoverflow.com/a/78679166/21691539)。

到目前为止我发现的最简单的解决方案是:

// in the spirit of std::aligned_storage
// can be on the stack or on the heap
template <typename T, std::size_t N>
struct Storage {
    alignas(T) unsigned char storage[N * sizeof(T)];
}

auto *wrapped_storage = new Storage<T,N>;
auto *storage = wrapped_storage.storage;

但只有在编译时已知对象数量时它才有效。

使原始存储适当对齐过度对齐类型的正确方法是什么?

c++ memory-management alignment heap-memory new-operator
1个回答
0
投票

从 C++17 开始:

// properly aligned heap storage to hold N contiguous T objects
unsigned char *storage = std::aligned_alloc(alignas(T),N*sizeof(T));
...
// releasing memory
std::free(storage);

用于在位置

i
创建非隐式生命周期对象的代码片段:

// placement-new
new(storage+i*sizeof(T)) T(<constructor args>);
...
// destroying non-trivially destructible object is mandatory before releasing storage
T* toDelete = std::launder(reinterpret_cast<T*>(storage+i*sizeof(T)));
toDelete->~T(); // destroy object but don't deallocate memory

这只是一个低级示例,使用智能指针进行更智能的实现会更好。

© www.soinside.com 2019 - 2024. All rights reserved.