C getaddrinfo和getnameinfo的正确用法

C getaddrinfo和getnameinfo的正确用法,c,tcp,ip,C,Tcp,Ip,在我的C程序中,我使用getaddrinfo从主机名获取IP地址,并使用getnameinfo从IP地址获取主机名。这两个功能是互补的。我在mangetaddrinfo中读到,我必须使用freeaddrinfo()函数来释放为动态分配的链表res分配的内存。因此,我的代码如下所示: if ((err = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) { printf("error %d\n", err); return 1

在我的C程序中,我使用
getaddrinfo
从主机名获取IP地址,并使用
getnameinfo
从IP地址获取主机名。这两个功能是互补的。我在
mangetaddrinfo
中读到,我必须使用
freeaddrinfo()
函数来释放为动态分配的链表
res
分配的内存。因此,我的代码如下所示:

if ((err = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
  printf("error %d\n", err);
  return 1;
}

addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr;
printf("%s\n", inet_ntoa(addr));

freeaddrinfo(res);
但是对于
getnameinfo
我没有看到任何类似的功能,即
freenameinfo

为什么我在使用
getaddrinfo
时需要释放,而在
getnameinfo
时不需要释放。为什么我需要自由?早些时候,当我使用
gethostbyaddr
时,不需要释放内存。为什么这是不同的


gethostbyaddr
相比,
getaddrinfo
有什么优势?后者是否已弃用,是否应仅使用前者?为什么?

getaddrinfo
的手册页,它会向您返回一个动态分配的链接列表。 因为它执行了内存分配,所以它也可以处理空闲内存

函数的作用是:释放分配给用户的内存 动态分配的链表资源

还要注意,函数签名包含一个
struct addrinfo**
,这是一个很好的提示,表明库函数正在代表您进行分配,并将指针返回给您

   int getaddrinfo(const char *node, const char *service,
                       const struct addrinfo *hints,
                       struct addrinfo **res);

对于
getnameinfo()
,它要求调用方分配
const struct sockaddr*
,因此调用方有责任释放它,并且没有相应的库调用来释放它

   int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                   char *host, size_t hostlen,
                   char *serv, size_t servlen, int flags);

gethostbyaddr
的手册页中,它声明自己已被弃用

gethostbyname*()、gethostbyaddr*()、herror()和hstrerror() 功能已经过时。应用程序应使用getaddrinfo(3), getnameinfo(3)和gai_strerror(3)

此时,我通常停止阅读,不再使用
gethostbyaddr
,而是选择
getaddrinfo


为什么不推荐使用这些函数?可能有很多原因,但告诉我们遗留函数不支持
IPv6
,以及as@R。。下面提到,它们是线程安全的。

您可能会喜欢,尤其是@R…,谢谢我找到了一个参考并更新了答案。
getaddrinfo
是否需要释放错误内存?我在任何地方都看不到这些信息。我有一个使用它的程序,唯一不调用free的地方是错误,valgrind抱怨内存丢失。@Quantum物理学家,我真的不确定。如果在任何地方都没有记录,那么很可能是必须咨询的情况。@merlin2011这是合理的。谢谢你抽出时间。