Will gethostbyname_r leak memory if the pointers in the hostent is not freed?

c, gethostbyaddr, linux, networking, posix

Solution

You should print out the values of the pointers in that struct to find out the answer to your question. You'll discover that they all point to data inside the buffer you allocated.

So a single `free` is all you need to free up all the memory.

But this also means that you must not free that allocation until you've finished using or copying whatever data you're interested in. You're freeing too early in your code.

Problem

The prototype of `gethostbyname_r` is: ``` int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop); ``` To avoid the non-reentrant `gethostbyname`, I wrote up these stuff: ``` int host2addr(const char *host, struct in_addr *addr) { struct hostent he, *result; int herr, ret, bufsz = 512; char *buff = NULL; do { char *new_buff = (char *)realloc(buff, bufsz); if (new_buff == NULL) { free(buff); return ENOMEM; } buff = new_buff; ret = gethostbyname_r(host, &he, buff, bufsz, &result, &herr); bufsz *= 2; } while (ret == ERANGE); if (ret == 0 && result != NULL) *addr = *(struct in_addr *)he.h_addr; else if (result != &he) ret = herr; free(buff); return ret; } ``` This is pretty the same as the example in GNU document and also the implemention in eglibc-2.15 for `gethostname`. But I noticed that, there are `h_name`, `h_aliases`, `h_addr_list` in a `struct hostent`: ``` struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */ } ``` Therefore I wonder if that really do not matter not to free the contents those pointers refer to. Is there some other mechanism handling those memories?

Original source