Casting std::unique_ptr<uint8_t[]> to struct unique_ptr without losing uint8_t[] buffer

154 Views Asked by At

Is there a way to cast a std::unique_ptr<uint8_t[]>(n) to std::unique_ptr</*some_struct*/> so that struct points to the same address as uint8_t ptr was as well as saving that buffer?

auto buffer = std::make_unique<uint8_t[]>(100);
std::unique_ptr<dummy> header = std::move(buffer); // error
struct dummy // string data
{
    uint64_t unk1; // 0x0

    uint64_t string_offset; // 0x8

    uint32_t c59d1c81; // 0x10

    uint16_t byte_length; // 0x14
    uint16_t string_length; // 0x16

    uint64_t unk2; // 0x18

    uint8_t* get_string() { return (uint8_t*)(uint64_t(this) + 0x8 + string_offset); }
};

In this example, buffer holds 0x20 bytes of dummy struct. However, it also contains a string which is obtainable by string_offset member and get_string method.

1

There are 1 best solutions below

5
Jarod42 On BEST ANSWER

Ignoring possible aliasing/alignment issues, you might do

auto buffer = std::make_unique<uint8_t[]>(100);
std::unique_ptr<dummy, Deleter> header(reinterpret_cast<dummy*>(buffer.release()));

With

struct Deleter
{
    void operator()(dummy* p) const {
        p->~dummy(); // Noop in your case
        delete[] reinterpret_cast<uint8*>(p);
    }
};