在gethostbyname_r后不管塞给它的hostent,是否会有内存泄漏问题?
int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
为了避开非线程安全的gethostbyname,想用这货,用起来类似这样:
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; }
基本上跟GNU官方文档里的例子一致(GNU的还少了个free的样子)。
但是对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 */ } #define h_addr h_addr_list[0] /* for backward compatibility */
这里面有h_name,h_aliases,h_addr_list ... 我又翻看了下eglibc-2.15的gethostbyname的源码,逻辑基本上跟我上面这段一样。但是,这些东西没释放的话,真的没问题吗?
在stackoverflow得到答案了...
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.