I need to deal with two struct addrinfo
pointers. Since I'm coding in C++(11), I've to make my code exception-safe. Indeed, my costructors may throw a runtime_error
.
When you don't need that kind of struct anymore, you should call freeaddrinfo
in order to free the list inside the struct. Please consider the following code:
#include <memory>
#include <netdb.h>
class SomeOtherClass
{
public:
SomeOtherClass() : hints(new addrinfo), result(new addrinfo) { /*stuff*/ }
~SomeOtherClass() { freeaddrinfo(result.get()); } // bad things will happen
private:
std::unique_ptr<addrinfo> hints, result;
};
class MyClass : public SomeOtherClass
{
public:
MyClass() { /* hints initialization, call to getaddrinfo, etc. */ }
private:
// ...
};
My questions are:
addrinfo
is an "old" C structure, with no ctor/dtor to call: is it safe to use new?getaddrinfo
requires a pointer to a pointer to a addrinfo
struct: how should I pass it via smart pointers? freeaddrinfo
? It's considered unsafe to delete (or better free
) the pointer that the smart pointer is holding.For hints
there is no problem, since its lifetime is smaller.
For any addrinfo
you allocate yourself, it is safe to use new
and delete
, so you can use the default implementation of unique_ptr
to handle that.
For any addrinfo
that getaddrinfo()
allocates, you must use freeaddrinfo()
to free it. You can still use unique_ptr
for that, but you must specify freeaddrinfo()
as a custom Deleter
, eg:
class SomeOtherClass
{
public:
SomeOtherClass() : hints(new addrinfo), result(nullptr, &freeaddrinfo) { /*stuff*/ }
private:
std::unique_ptr<addrinfo> hints;
std::unique_ptr<addrinfo, void(__stdcall*)(addrinfo*)> result;
};
Then you can do this:
getaddrinfo(..., &result);
Or this, if std::unique_ptr
does not override the &
operator:
addrinfo *temp;
getaddrinfo(..., &temp);
result.reset(temp);
UPDATE: a better option is to use decltype
and let the compiler deduce the function type of the Deleter
for you:
std::unique_ptr<addrinfo, decltype(&freeaddrinfo)> result;
In addition to other answers: C++23 introduces a new feature for smart pointers interacting with C-style output parameters. Now, instead of replacing the managed object with a temporary value, we can use std::out_ptr()
:
getaddrinfo(..., std::out_ptr(result));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With