如何在具有动态对齐要求的C ++中分配内存?

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

在C ++中分配和使用具有动态指定对齐方式的缓冲区的正确方法是什么?我想到的用例是Vulkan动态统一缓冲区(请参见this previous question,该缓冲区抽象地讨论了所需的过程),针对对齐的约束是通过minUniformBufferOffsetAlignmentVkPhysicalDeviceLimits属性给出的,在编译时已知。

我最初以为我可以使用operator new(std::align_val_t)做类似的事情

Foo* buffer = new(std::align_val_t{alignment}) Foo[n];

但是不会编译(至少在MSVC上)。

[我也看过Timur Doumler的CppCon演示文稿“ Type punning in modern C++”,它指出,对reinterpret_cast之类的结果使用std::aligned_alloc会导致不确定的行为。

到目前为止,我已经提出了以下内容:

std::size_t n = getNumberOfElements(); // possibly not known at compile time
std::size_t alignment = getRequiredAlignment(); // not known at compile time

void* storage = std::aligned_alloc(sizeof(Foo[n]), alignment); // _aligned_malloc on MSVC
Foo* buffer = new(storage) Foo[n];

// do stuff with buffer

for(std::size_t i = 0; i < n; ++i) { buffer[i].~Foo(); }
std::free(storage); // _aligned_free on MSVC

我在这里错过了会导致不确定行为的东西吗?

c++ memory-management c++17
1个回答
1
投票
[Foo[n]是一个可变长度的数组,它们不是标准C ++的一部分。

您可以在不使用VLA的情况下执行以下操作:

Foo* storage = static_cast<Foo*>(std::aligned_alloc(n * sizeof(Foo), alignment)); std::uninitialized_default_construct_n(storage, n); // ... std::destroy_n(storage, n); free(storage);

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