I assume you cannot modify SMOE_STRUCT
to add a destructor to it. This leaves you with two options: a custom deleter, and encapsulation.
First, you could create a custom deleter for use with std::unique_ptr
:
struct SOME_STRUCT_Deleter
{
void operator() (SOME_STRUCT *p) const
{
delete[] p->SOME_MEMBER;
delete p;
}
};
std::unique_ptr<SOME_STRUCT, SOME_STRUCT_Deleter> ptr{new SOME_STRUCT};
ptr->SOME_MEMBER = new BYTE[100];
CallSomeAPI(ptr.get());
If you find that, unlike the situation described in your question, shared ownership would suit you better than exclusive one, you can use the deleter with a shared_ptr
as well, like this:
std::shared_ptr<SOME_STRUCT> ptr{new SOME_STRUCT, SOME_STRUCT_Deleter{}};
ptr->SOME_MEMBER = new BYTE[100];
CallSomeAPI(ptr.get());
A second option, which I find preferable, is to wrap SOME_STRUCT
:
struct SOME_STRUCT_plus_plus
{
SOME_STRUCT s;
~SOME_STRUCT_plus_plus()
{
delete[] s.SOME_MEMBER;
}
SOME_STRUCT_plus_plus()
{
s.SOME_MEMBER = new BYTE[100];
}
};
std::unique_ptr<SOME_STRUCT_plus_plus> ptr{new SOME_STRUCT_plus_plus};
CallSomeAPI(&ptr->s);
You could even "wrap" it by making SOME_STRUCT_plus_plus
derive from SOME_STRUCT
instead of aggregating it, which would give you direct access to members without the need to go through s
. At the same time, it could lead to memory leaks if someone cast SOME_STRUCT_plus_plus*
to SOME_STRUCT*
and then called delete
on it.
std::unique_ptr
? The new smart pointers shouldn't really be seen as a replacement for normal pointer, but more like handling ownership: Can a resource (memory, file, device, etc.) be owned by multiple owners (std::shared_ptr
) or by only a single owner (std::unique_ptr
) at a time? – Some programmer dudeSOME_STRUCT s; std::vector<BYTE> buffer(100); s.SOME_MEMBER = &buffer[0]; CallSomeAPI(&s);
-- yes, this works. – Ulrich Eckhardt