10
struct hostent *gethostbyname(const char *name)

hostent.h_addr_list は可変長のフィールドであることに注意してください。

gethostbyname構造体を指すポインターを返すが、呼び出し元がリソースを解放する必要がない実装を関数にどのように持たせますか?

R. Stevens 著の有名な本 Unix Network Programming Vol 1 で使用されているすべての例には、返されたポインタを解放するコードが含まれていません。これらは無知ではないと思います。また、MSDN の 1 つの例では、同じことを行っています。

4

5 に答える 5

5

リンク先のmanページに答えがあります。

非 NULL の場合、戻り値は静的データを指す場合があります。以下の注を参照してください。

そして少し後で:

関数 gethostbyname() および gethostbyaddr() は、静的データへのポインターを返す場合がありますが、これは後の呼び出しで上書きされる可能性があります。

于 2012-07-18T15:07:49.123 に答える
3

実装がアドレスの任意の大きなリストを処理したいと仮定すると、次のようにすることができます:

struct hostent *gethostbyname(const char *name) {
    static struct hostent *results = 0;
    static size_t resultsize = 0;
    size_t count = get_count_of_addresses(name)
    if (count > resultsize) {
        struct hostent *tmp = realloc(results, N * count + M);
        if (tmp) {
            results = tmp;
            resultsize = count;
        } else {
            // handle error, I can't remember what the docs say
        }
    }
    fill_in_hostent(results, name);
    return results;
};

オプションで、ソケット ライブラリは、デバッグ ツールがメモリ リークを報告するのを避けるために、終了時に何かを解放する (ハンドラーresultsをインストールするなど) ことができます。atexit

構造体のサイジングとそれへの入力の間にアドレスの数が変化する可能性を無視しました.実際には、DNS結果を取得してからそれを処理するため、それは不可能です. DNS の結果に疑似コード表現が導入されるのを避けるために、2 つの別個の呼び出しとして残しました。

于 2012-07-18T15:20:36.507 に答える
2

静的メモリを指している可能性があります。複数の結果を保持したい場合は、その詳細コピーを作成する必要があります。その構造自体にポインターが含まれているため、浅いコピーではありません。

スレッドセーフに注意してください。

于 2012-07-18T15:08:45.647 に答える
1

おそらく静的メモリを指しています。つまり、すべての呼び出しで同じポインタです。

于 2012-07-18T15:04:27.677 に答える