2012-03-22 390 views
0

我正在学习套接字编程,并且我遇到了这段代码。关于memset的困惑

struct addrinfo hints, *res, *p; 
int status; 
char ipstr[INET6_ADDRSTRLEN]; 

if (argc != 2) { 
    fprintf(stderr,"usage: showip hostname\n"); 
    return 1; 
} 

memset(&hints, 0, sizeof hints); 
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version 
hints.ai_socktype = SOCK_STREAM; 

if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); 
    return 2; 
} 

我明白这一切,除了一个。为什么这个代码memset了结构提示,但不是* res和* p?

+1

更好的风格是初始化'提示'而不是调用'memset'。 – 2012-03-22 10:42:15

回答

3

res指针将由getaddrinfo函数填充,因此不需要通过零初始化。另一方面需要初始化另一个hints,因此将整个结构设置为零,然后设置仅需要设置的两个字段。

由于您在代码中不使用p - 我无法评论它。

0

它不应该只是你所有的0的memset提示。另外,res和p指针只在memset调用时没有定位到任何位置。

这是预期的行为。让我知道你的例外,我将能够更好地帮助你。

0

为什么这段代码memset了结构提示,但不是* res和* p?

因为,您只调用一次memset并仅将&提示作为参数传递给该memset。

memset(&hints, 0, sizeof hints); 

如果你想memset的* RES & * P,首先你需要同他们onlypointers,然后你需要通过将其作为参数seperately对于他们中的每一个调用memset的分配内存。

+0

所以我可以memset * res,但它没有任何意义,因为getaddrinfo会覆盖它吗? – 2012-03-22 15:30:26

+0

你不能memset'* res',因为指针是无效的(包含“垃圾”,因为它没有被初始化 - 因此指向无效的“对象”)。你可以memset指针本身('res'),但是如果你想这样做,分配零('res = 0;')也很容易。你说得对,函数调用会在它返回时为'res'赋值。 - 澄清:'res'的类型是'struct addrinfo *'(指向addrinfo结构的指针),'* res'的类型是'struct addrinfo'(结构本身,而不是指针) – Attila 2012-03-23 20:32:09

1

getaddrinfo的说明指出

的的getaddrinfo()函数分配和初始化addrinfo中结构的一个链表,一个用于相匹配的节点和服务中的每个的网络地址,受提示施加的任何限制,并返回一个指向res中列表开始的指针。

这意味着你不会在严格需要(否则该函数可能会产生不希望的输出)hints中获得任何其他信息。此外,该函数的“实际”结果返回res,这意味着res的当前内容被覆盖,因此您不会在函数调用之前关心内存中的内容(只要您不打算解释如果该功能失败)。

由于结构的成员(如addrinfo)在声明该类型的变量时没有以任何方式初始化,所以hints最初包含“垃圾” - 无论发生在分配变量的内存中。因此,代码调用memset以简单/快速的方式将所有成员清零(而不是逐个设置成员变量为零)。