使用addrinfo结构的智能指针

edm*_*dmz 3 sockets smart-pointers c++11

我需要处理两个struct addrinfo指针.由于我是用C++编写的(11),我要使代码异常安全.实际上,我的结构可能会抛出一个runtime_error.当你不再需要那种结构时,你应该调用freeaddrinfo以释放结构中的列表.请考虑以下代码:

#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:
    // ...
};
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. addrinfo 是一个"旧的"C结构,没有ctor/dtor可以调用:使用new是否安全?
  2. getaddrinfo需要一个指向addrinfo结构指针的指针:我应该如何通过智能指针传递它?
  3. 打电话freeaddrinfo怎么样?删除(或更好free)智能指针所持有的指针被认为是不安全的.

因为hints没有问题,因为它的寿命较短.

Rem*_*eau 7

对于任何addrinfo你分配你自己,它是安全的使用newdelete,所以你可以使用默认的实现unique_ptr来处理.

对于任何addrinfogetaddrinfo()分配,您必须使用freeaddrinfo()来释放它.您仍然可以使用unique_ptr它,但您必须指定freeaddrinfo()为自定义Deleter,例如:

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;
};
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

getaddrinfo(..., &result);
Run Code Online (Sandbox Code Playgroud)

或者,如果std::unique_ptr不覆盖&运算符:

addrinfo *temp;
getaddrinfo(..., &temp);
result.reset(temp);
Run Code Online (Sandbox Code Playgroud)

更新:更好的选择是使用decltype并让编译器推导出Deleter适合您的函数类型:

std::unique_ptr<addrinfo, decltype(&freeaddrinfo)> result;
Run Code Online (Sandbox Code Playgroud)

  • 就个人而言,我不会在堆上分配`hints`,所以我只是让它成为该类的本地成员而根本没有动态分配.然后没有部分构造的机会(在这个例子中,无论如何).你没有选择`result`的分配方式. (2认同)