使用addrinfo结构的智能指针

时间:2014-02-21 18:23:32

标签: sockets c++11 smart-pointers

我需要处理两个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:
    // ...
};

我的问题是:

  1. addrinfo是一个“旧的”C结构,没有ctor / dtor可以调用:使用new是否安全?
  2. getaddrinfo需要一个指向addrinfo结构的指针的指针:我应该如何通过智能指针传递它?
  3. 如何致电freeaddrinfo?删除(或更好free)智能指针所持有的指针被认为是不安全的。
  4. 对于hints,没有问题,因为它的生命周期较短。

1 个答案:

答案 0 :(得分:7)

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

对于addrinfo分配的任何getaddrinfo(),您必须使用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;
};

然后你可以这样做:

getaddrinfo(..., &result);

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

addrinfo *temp;
getaddrinfo(..., &temp);
result.reset(temp);

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

std::unique_ptr<addrinfo, decltype(&freeaddrinfo)> result;