[英]casting char-array into array of PODs in C++
What's the correct way to write the code below? 编写下面代码的正确方法是什么?
I have a memory manager which provides me with char *
's, but I need to work with arrays of uint32_t
. 我有一个为我提供
char *
的内存管理器,但是我需要使用uint32_t
数组。 How can I work around the strict aliasing rule? 如何解决严格的别名规则? I understand that with a single object it's advised just to copy the contents with
memcpy()
but that solution is not acceptable for an array of objects. 我了解到,建议仅使用一个对象使用
memcpy()
复制内容,但该解决方案对于对象数组不可接受。
char* ptr = manager()->Allocate(1000 * sizeof(uint32_));
uint32_t* u32ptr = reinterpret_cast<uint32_t*>(ptr);
....
u32ptr[x] = y;
You can use placement-new: 您可以使用新的展示位置:
uint32_t* u32ptr = new(ptr) uint32_t[1000];
Note that after this, the effective type of the storage is int32_t
, and you may not use ptr
any more. 请注意,此后,存储的有效类型为
int32_t
,您可能不再使用ptr
了。 You don't have to do anything special with the char
s, because for types with a trivial destructor, you can end their lifetime simply by reusing the storage. 您不必对
char
进行任何特殊处理,因为对于带有琐碎析构函数的类型,您可以简单地通过重用存储来结束它们的生命。
You could make the Manager
class return std::unique_ptr<void, Manager::Deleter>
( that is, with a unique pointer with a custom deleter ). 您可以使
Manager
类返回std::unique_ptr<void, Manager::Deleter>
(即,使用带有自定义删除器的唯一指针 )。 This makes the allocation use RAII to automagically deallocate when you go out of scope. 当您超出范围时,这将使分配使用RAII自动取消分配。 And instead of using a pointer, prefer a
gsl::span
In that case, you could write: 并且不使用指针,而是使用
gsl::span
在这种情况下,您可以编写:
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);
Another alternative is to template the Manager class, or the allocation method, on an element type, and have it take care of things: 另一种方法是到模板Manager类,或分配方法,在一个元素类型,并把它照顾的事情:
auto p = manager()->Allocate<std::uint32_t>(1000);
... and p
will be an std::unique_ptr<uint32_t>
to costructed uint32_t
s. ...和
p
将是构造的uint32_t
的std::unique_ptr<uint32_t>
。 Not that you need any construction for them, but still. 并不是说您需要对其进行任何构造,但是仍然如此。
Caveat: In both cases, you must not return p
from the scope you're in, since it is a non-owning pointer, and the memory will be freed when you leave the scope. 注意:在这两种情况下, 都不能从所在的作用域中返回
p
,因为它是一个非所有者指针,并且在离开作用域时将释放内存。 p
is for local work only. p
仅用于本地工作。 If you want to keep the memory out-of-scope you have to return the unique_ptr
. 如果要使内存不在范围之内,则必须返回
unique_ptr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.