2

そのような関数を呼び出すと、inet_ntoachar*が返されます。割り当てられたメモリを解放する責任は誰にありますか?

私の方法は次のようになります。

char* inet_aton_(unsigned int atonIp){
    in_addr sin_addr;
    sin_addr.s_addr = atonIp;
    return inet_ntoa(sin_addr);
}
4

3 に答える 3

11

そのためのマニュアルを確認する必要があります。

$ man inet_ntoa

... inet_ntoa()関数は、ネットワークバイトオーダーで指定されたインターネットホストアドレスを、IPv4ドット付き10進表記の文字列に変換します。文字列は静的に割り当てられたバッファに返され、その後の呼び出しで上書きされます。

これは、アプリケーションに静的に割り当てられたバッファーがあり、そこにあるものに対して責任があることを意味します。アプリケーションでinet_ntoa()を呼び出すたびに、この領域が上書きされます。たとえば2つのアドレスを保持する必要がある場合は、このデータを別のバッファにコピーする必要があります。また、スレッド化されたアプリケーションで正しい方法で使用する必要があります。たとえば、2つのスレッドが同時にinet_ntoaを呼び出す場合、間違った結果が得られるか、異なるパラメーターを使用してinet_ntoaを2回別々に呼び出すと同じ結果が返されます。

この種の質問がある場合は、ソースコードも調べる必要があります。たとえば、「inet_ntoasource」を検索する場合。いくつかの例に遭遇するかもしれません。freebsdまたはms。実装例の1つを以下に示します(freebsdから)。

char *
inet_ntoa(struct in_addr ina)
{
    static char buf[4*sizeof "123"];
    unsigned char *ucp = (unsigned char *)&ina;

    sprintf(buf, "%d.%d.%d.%d",
        ucp[0] & 0xff,
        ucp[1] & 0xff,
        ucp[2] & 0xff,
        ucp[3] & 0xff);
    return buf;
}

ご覧のとおり、この目的のためにのみ静的にバッファが割り当てられています。これにより、バッファを管理する必要がないため、inet_ntoaの使用が非常に簡単になりますが、スレッドセーフではなくなります。

もう1つ、inet_ntoaはシステムコールではありません。inetライブラリが提供する便利な関数と言えます。

于 2012-08-21T22:10:11.363 に答える
3

引用マンページ

文字列は静的に割り当てられたバッファに返され、後続の呼び出しで上書きされます。

これは、誰もメモリを解放する必要がなく、解放しようとすべきではないことを意味します。

于 2012-08-21T22:10:14.483 に答える
1

それで、最初に; これらの関数はIPv6をサポートしていないため、非推奨になりました。次に...ドキュメントを参照してください。関数がポインタを返すときは、誰がポインタの割り当てを解除するのかを明確に文書化する必要があります。

この場合、あなたはそれを割り当て解除する責任がありません(あなたもそうすべきではありません!)。

inet_ntoa()は、関数を呼び出すたびに上書きされる静的バッファー内のドットと数値の文字列を返します。

于 2012-08-21T22:11:59.273 に答える