Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/241.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解C中的getaddrinfo函数_C_Linux_Network Programming_Getaddrinfo - Fatal编程技术网

理解C中的getaddrinfo函数

理解C中的getaddrinfo函数,c,linux,network-programming,getaddrinfo,C,Linux,Network Programming,Getaddrinfo,我不熟悉C和socket编程,只是关于getaddrinfo函数的一个问题。getaddrinfo的功能原型是: int getaddrinfo(const char *host, const char *service, const struct addrinfo *hints, struct addrinfo **result); 和getaddrinfo返回一个结果,该结果指向addrinfo结构的链接列表,每个结构都指向对应于主机和服务的套接字地址结构。 以下是我的问题: Q1为什么

我不熟悉C和socket编程,只是关于
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**
参数

逻辑清楚吗?给定
类型
,如果要将其作为参数返回,则必须将其定义为指向
类型
的指针

总之,在我们的例子中,函数
getaddrinfo
需要修改类型为
struct addrinfo*
的变量,因此
struct addrinfo**
是参数类型

仅提及此参数的含义:

getaddrinfo()函数分配并初始化addrinfo结构的链表,每个与节点和服务匹配的网络地址对应一个链表,受提示施加的任何限制,并返回指向列表开头的指针(以res表示)。链表中的项由ai_next字段链接

正如您所看到的,我们实际上在函数中有一个分配。因此,最终需要释放此内存:

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


为什么不只是一个
类型*
参数? 您的代码示例导致未定义的行为,当我运行它时,它导致程序崩溃

为什么?是我在上面写的,在C中,参数是通过值传递的。这意味着在
func(int c)
函数的情况下,以这种方式调用

int b = 1234;

funct(b);
函数内部使用的参数
c
将是
b
的一个副本,对其进行的任何更改都不会在函数之外继续存在

func(char*ptr)
的情况下也会发生同样的情况(请注意巨大的空格,以强调类型是
char*
,变量是
ptr
):对
ptr
的任何更改都不会在函数之外继续存在**您可以更改它指向的内存,这些更改将在函数返回后可用,但作为参数传递的变量将与调用
func()
之前相同

在您的示例中,
test
调用之前,
ptr\u main
的值是多少?我们不知道,因为变量未初始化。因此,行为是未定义的

如果您仍有疑问,这里是一个程序,它演示了无法从函数外部访问通过value获得的新分配地址:

#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);
}
即使在函数调用之后,
ptr\u main
的值也与我初始化它后的值相同(
0x7777


“这只是一个唯一的套接字地址”不正确。例如,主机名可能有许多不同的地址与之关联。“并让result(struct addrinfo*)指向它”如果您的函数想要更改某些内容,它需要接受指向该内容的指针作为参数<代码>结果是一个指针,所以它需要一个指向指针的指针。谢谢你的回答,所以对于问题2,我也可以像
int test(char*ptr){ptr=malloc(10);}
,所以参数不需要是s
char**ptr
@amjad-Uhm。。。不,我可能不够清楚,我得重写一下。参数是按值传递的,因此ptr在函数外部不可用(您将无法释放它)。所以如果你需要返回一个指针,你需要一个双指针参数
main-1: 0000000000007777
test:   0000000000A96D60
main-2: 0000000000007777