You could make the Manager
class return std::unique_ptr<void, Manager::Deleter>
( that is, with a 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 gsl::span
In that case, you could write:
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:
auto p = manager()->Allocate<std::uint32_t>(1000);
... and p
will be an std::unique_ptr<uint32_t>
to costructed uint32_t
s. 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
is for local work only. If you want to keep the memory out-of-scope you have to return the unique_ptr
.