3

のプロトタイプgethostbyname_rは次のとおりです。

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ドキュメントの例と、eglibc-2.15forの実装とほぼ同じですgethostname

h_nameしかし、私は、:にh_aliases、、があることに気づきh_addr_listました。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 */
}

したがって、それらのポインタが参照しているコンテンツを解放しないことは本当に問題ではないのだろうか。それらの記憶を処理する他のメカニズムはありますか?

4

1 に答える 1

5

質問に対する答えを見つけるには、その構造体のポインターの値を出力する必要があります。それらはすべて、割り当てたバッファ内のデータを指していることがわかります。

したがって、freeすべてのメモリを解放するために必要なのは1つだけです。

ただし、これは、関心のあるデータの使用またはコピーが完了するまで、その割り当てを解放してはならないことも意味します。コードの初期段階で解放しすぎています。

于 2013-01-26T17:02:58.233 に答える