对 memset 感到困惑
Posted
技术标签:
【中文标题】对 memset 感到困惑【英文标题】:Confused about memset 【发布时间】:2012-03-22 10:18:17 【问题描述】:我在学习socket编程,遇到了这段代码。
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'ed 结构提示而不是 *res 和 *p?
【问题讨论】:
更好的方式是初始化hints
而不是调用memset
。
【参考方案1】:
res
指针将由getaddrinfo 函数填充,因此不需要初始化为零。另一方面,hints
需要初始化,因此将整个结构设置为零,然后设置唯一需要设置的两个字段。
由于您没有在代码中使用p
- 我无法对此发表评论。
【讨论】:
【参考方案2】:getaddrinfo 的描述表明
getaddrinfo() 函数分配和初始化一个 addrinfo 结构的链表,每个匹配节点和服务的网络地址都有一个,受提示施加的任何限制,并在 res 中返回指向列表开头的指针。
这意味着您不需要hints
中的任何其他信息,而不是绝对必要的(否则该函数可能会产生不希望的输出)。此外,函数的“真实”结果在res
中返回,这意味着res
的当前内容被覆盖,所以你并不关心函数调用之前那里的内容(只要你是如果函数失败,则不会解释它)。
由于结构的成员(如addrinfo
)在声明该类型的变量时没有以任何方式初始化,hints
最初包含“垃圾”——无论在分配变量的内存中发生了什么.因此,代码调用memset
以简单/快速的方式将所有成员清零(而不是将成员变量逐个设置为零)。
【讨论】:
【参考方案3】:它不应该因为你只对全 0 进行 memset 提示。 res 和 p 也只是指针,在 memset 调用时不定位到任何位置。
这是预期的行为。让我知道您的例外情况,我将能够更好地帮助您。
【讨论】:
【参考方案4】:为什么这段代码 memset'ed 结构提示而不是 *res 和 *p?
因为,您只调用了一次 memset,并且只将 &hints 作为参数传递给该 memset。
memset(&hints, 0, sizeof hints);
如果你想 memset *res & *p,首先你需要为它们分配内存,因为它们只是指针,然后你需要通过将它们作为参数传递来分别为它们中的每一个调用 memset。
【讨论】:
所以我可以 memset *res,但这没有意义,因为 getaddrinfo 无论如何都会覆盖它? 您不能 memset*res
,因为指针无效(包含“垃圾”,因为它尚未初始化 - 因此指向无效的“对象”)。您可以 memset 指针本身 (res
),但如果您想这样做,也很容易将零分配给它 (res=0;
)。你是对的,函数调用将在返回时为res
分配一个新值。 -- 澄清:res
的类型是struct addrinfo *
(指向addrinfo结构的指针),*res
的类型是struct addrinfo
(结构本身,不是指针)以上是关于对 memset 感到困惑的主要内容,如果未能解决你的问题,请参考以下文章