2

如果我调用这样的函数inet_ntoa,则返回 char*。谁负责释放分配的内存?

我的方法如下所示:

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() 函数将以网络字节顺序给出的 Internet 主机地址转换为 IPv4 点分十进制表示法的字符串。该字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。

这意味着在您的应用程序中,您将拥有一个静态分配的缓冲区,并且您对其中的内容负责。应用程序中对 inet_ntoa() 的每次调用都会覆盖该区域。如果您需要保留例如两个地址,则必须将此数据复制到另一个缓冲区。您还负责在线程应用程序中以正确的方式使用,例如,如果您有两个线程同时调用 inet_ntoa,您将得到错误的结果,或者使用不同参数对 inet_ntoa 的两次单独调用将返回相同的结果。

当您有此类问题时,您还应该查看源代码。例如,如果您搜索“inet_ntoa 源”。你可能会遇到一些例子;freebsdms。下面是一个示例实现(来自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 的使用非常容易,因为您不需要管理缓冲区,但也使其不是线程安全的。

另一件事,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 回答