在 C++ 中将字符数组转换为 PODs 的数组

casting char-array into array of PODs in C++

下面代码的正确写法是什么?

我有一个内存管理器,它为我提供 char *,但我需要使用 uint32_t 的数组。我该如何解决严格的别名规则?我知道对于单个对象,建议只使用 memcpy() 复制内容,但该解决方案对于对象数组是不可接受的。

char* ptr = manager()->Allocate(1000 * sizeof(uint32_));
uint32_t* u32ptr = reinterpret_cast<uint32_t*>(ptr);
....
u32ptr[x] = y;

您可以使用 placement-new:

uint32_t* u32ptr = new(ptr) uint32_t[1000];

请注意,此后存储的有效类型为uint32_t,您不能再使用ptr。您不必对 char 做任何特殊的事情,因为对于具有普通析构函数的类型,您可以简单地通过重用存储来结束它们的生命周期。

你可以写 Manager class return std::unique_ptr<void, Manager::Deleter>( 也就是说,用 unique pointer with a custom deleter). This makes the allocation use RAII to automagically deallocate when you go out of scope. And instead of using a pointer, prefer a 在这种情况下,你可以写:

constexpr const length = 1000;
auto allocated = manager()->Allocate(
    length * sizeof(std::uint32_t), 
    alignof(uint32_t) // supporting alignment here is important, otherwise
                      // you'll have to manually take care of that yourself
);
auto p = gsl::span<uint32_t>(new(allocated.get()) std::uint32_t[length], length);

另一种方法是在元素类型上为管理器 class 或分配方法创建模板,并让 处理事情:

auto p = manager()->Allocate<std::uint32_t>(1000);

... 并且 p 将是 std::unique_ptr<uint32_t> 到构造的 uint32_t。并不是说你需要为他们做任何建设,但仍然。

警告:在这两种情况下,您不得returnp in,因为它是一个非拥有指针,当你离开作用域时,内存将被释放。 p 仅适用于本地工作。如果你想让内存超出范围,你必须 return the unique_ptr.