如何解决了解C语言中的getaddrinfo函数
我是C和套接字编程的新手,只是一个关于getaddrinfo
函数的问题。 getaddrinfo
的函数原型为:
int getaddrinfo(const char *host,const char *service,const struct addrinfo *hints,struct addrinfo **result);
和getaddrinfo
返回一个结果,该结果指向addrinfo结构的链表,每个结构都指向与主机和服务相对应的套接字地址结构。
以下是我的问题:
Q1-为什么需要返回指向addrinfo
结构的链接列表的结果?我的意思是,给定主机和服务,这些只是一个唯一的套接字地址,怎么可能不止一个有效的套接字地址,所以需要一个链表?
Q2-最后一个参数是struct addrinfo **result
,为什么它是指向指针的指针?为什么不是struct addrinfo *result
,然后getaddrinfo
在内部创建某事物并让result
(struct addrinfo *
)指向它呢?
有人说这是由于内部getaddrinfo
调用malloc
而引起的,但是我也可以这样编码
int main()
{
char *ptr_main;
test(ptr_main);
free(ptr_main);
}
void test(char * ptr)
{
ptr = malloc(10);
}
因此该函数的参数为char *ptr
,而不是char **ptr
。
解决方法
getaddrinfo()
返回地址列表,因为主机名可以包含多个地址。例如,考虑那些需要通过不同IP分配访问者的高流量站点。
将gethostbyname(3)和getservbyname(3)函数提供的功能组合到一个接口中,但是与后面的函数不同,getaddrinfo()是可重入的,并允许程序消除IPv4与之相对-IPv6依赖项
它可能会触发DNS会话来解析主机名。如果是上述那些高流量站点,则相同的主机名将对应于实际地址列表。
您还问:
struct addrinfo **result
,为什么它是指向指针的指针?
在C语言中,指向某物的指针在必须修改时作为函数的参数传递。因此,例如,如果需要修改整数,则传递int *
。当您想通过参数返回某些内容时,这种特殊的修饰在C语言中非常常见。在前面的示例中,我们可以通过访问作为参数传递的指针来返回一个额外的整数。
但是,如果一个函数想分配一些东西怎么办?结果将在内部产生type * var = malloc()
,这意味着将返回指向type
的指针。为了将其作为参数返回,我们需要传递一个type **
参数。
逻辑清楚吗?给定一个type
,如果您想返回它作为参数,则必须将其定义为指向type
的指针。
最后,在我们的例子中,函数getaddrinfo
需要修改类型为struct addrinfo *
的变量,因此struct addrinfo **
是参数类型。
仅提及此参数的含义:
getaddrinfo()函数分配,并初始化addrinfo结构的链接列表,该列表针对与节点和服务匹配的每个网络地址,受提示强加的任何限制,并返回指向该地址的指针。 res列表的开头。链接列表中的项目通过ai_next字段链接。
如您所见,我们实际上在函数内部有一个分配。因此,最终需要释放此内存:
freeaddrinfo()函数释放为动态分配的链表资源分配的内存。
为什么不只是一个type *
参数?
您的代码示例导致未定义的行为,当我运行它时,导致程序崩溃。
为什么?我在上面写过,在C参数中通过值传递。这意味着在使用这种方式调用的func(int c)
函数的情况下
int b = 1234;
funct(b);
该函数内部使用的参数c
将是b
的副本,并且对其所做的任何更改都将无法在该函数外部保留。
在func(char * ptr)
情况下也会发生同样的情况(请注意要留有很大的空格,以强调类型char *
和变量ptr
的位置):{{1}上的任何更改}将无法在函数之外生存。 **您将能够更改其指向的内存,并且这些更改将在函数返回后可用,但是作为参数传递的变量将与调用ptr
之前的变量相同。>
在您的示例中,在调用func()
之前,ptr_main
的值是什么?我们不知道,因为变量尚未初始化。因此,行为是不确定的。
如果您仍然有疑问,这里是一个程序,该程序演示了无法从外部test
访问通过值获得的新分配地址:
the function
输出:
#include <stdlib.h>
#include <stdio.h>
void test(char * ptr)
{
ptr = malloc(10);
printf("test:\t%p\n",ptr);
}
int main()
{
char *ptr_main = (char *) 0x7777;
printf("main-1:\t%p\n",ptr_main);
test(ptr_main);
printf("main-2:\t%p\n",ptr_main);
}
即使在函数调用之后,main-1: 0000000000007777
test: 0000000000A96D60
main-2: 0000000000007777
的值也与我对其初始化后的值(ptr_main
)相同。
0x7777
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。