We can use std::unique_ptr
to hold a pointer allocated with malloc
which will be free
d appropriately.
However, the resulting std::unique_ptr
's size will be 2 pointers, one for the pointer to the object and one for the pointer to the deleter function instead of the usual 1 pointer to object and an implicit delete
. As one answer points out this can be avoided by writing a custom Unique_ptr
that knows the proper deleter function. This function can be made known using a template parameter to support any deleter function like so:
template <class T, void (*Deleter)(T *)>
struct Unique_ptr {
explicit Unique_ptr(T *t, void (*)(T *))
: t{t} {}
~Unique_ptr() {
Deleter(t);
}
//TODO: add code to make it behave like std::unique_ptr
private:
T *t{};
};
template <class T>
void free(T *t) {
std::free(t);
}
char *some_C_function() {
return (char *)malloc(42);
}
int main() {
Unique_ptr<char, free> p(some_C_function(), free); //fine
Unique_ptr q(some_C_function(), free); //should be fine
//with the right
//deduction guide
}
This would be really nice if we could use deduction guides to not have to specify the template parameters. Unfortunately I can't seem to get the syntax right. These attempts fail to compile:
template <class T, auto Deleter>
Unique_ptr(T *, Deleter)->Unique_ptr<T, Deleter>;
template <class T, void (*Deleter)(T *)>
Unique_ptr(T *, void (*Deleter)(T *))->Unique_ptr<T, Deleter>;
Alternatively one could write Unique_ptr<free> q(some_C_function());
in order to manually specify the function template parameter, but that creates issues with deducing T
.
What is the correct deduction guide to make Unique_ptr q(some_C_function(), free);
or Unique_ptr<free> q(some_C_function());
compile?