Custom deleter for unique_ptr

Sockets… why they are not included in the C++ standard? We had a lot of trouble wrapping BSD sockets C API into our C++ library. Recently, analyzing our application with valgrind I discovered memory leaks in one of the socket wrappers.

The raw pointer to C struct addrinfo was wrapped into unique pointer:

class IpSocket
{
    ...
private:
    std::unique_ptr<struct addrinfo> addresssInfo_;
};

The memory was allocated as

int result = getaddrinfo(host, post, &hints, &aInfo);
addressInfo_ = std::unique_ptr<struct addrinfo>(aInfo);

In our case, the IpSocket destructor will try to free memory by invoking the default deleter (delete operator) over object stored in addressInfo_. That is the problem, the getaddrinfo() allocates the memory using C function malloc and hence we need to invoke free() function to release this memory.

The manpage for getaddrinfo() says that the freeaddrinfo() function should be used to free memory. The quick look into freeaddrinfo() source confirms that the function does what we expected

void freeaddrinfo (struct addrinfo *ai)
{
    struct addrinfo *p;	
    while (ai != NULL)
    {
        p = ai;
        ai = ai->ai_next;
        free (p->ai_canonname);
        free (p);
    }
}

In order to force our unique_ptr use freeaddrinfo we need to define custom deleter and put it as a second template argument.

class IpSocket
{
private:
    struct AddressInfoDeleter
    {
            void operator()(struct addrinfo *p) { freeaddrinfo(p); }
    };

    std::unique_ptr<struct addrinfo, AddressInfoDeleter> addressInfo_;
};

Now the memory is released correctly.