我正在使用getaddrinfo()
函数,需要使用struct addrinfo **
来填充结果的链接列表,但是当我尝试以下代码时,我遇到了段错误...
int main() {
struct addrinfo **results;
getaddrinfo("localhost", "http", NULL, results); // segfault here
return 0;
}
我将struct addrinfo **results
传递给getaddinfo()
,预计这种类型,如何导致段错误?
如果我稍微改变我的代码......
int main() {
struct addrinfo *results;
getaddrinfo("localhost", "http", NULL, &results); // works
return 0;
}
我的代码工作正常。有什么不同?
results
最终将指向struct addrinfos
的链接列表,您可以通过此列表获取与您传入的第三个参数匹配的所有地址。函数将使指针指向链表,这就是预期指针地址的原因。传递struct addrinfo*
变量的地址时,可以指向列表。取消引用传递的变量将是正常的,因为取消引用的值是变量results
的值。 (这解释了为什么struct addrinfo *results;
和&results
的作品)。
它指向链表。来自getaddrinfo
的here来源
2201 int
2202 getaddrinfo (const char *name, const char *service,
2203 const struct addrinfo *hints, struct addrinfo **pai)
2204 {
...
...
2535 if (p)
2536 {
2537 *pai = p; // in your case this (pai) was uninitialized
2538 return 0;
2539 }
2540
2541 return last_i ? -last_i : EAI_NONAME;
2542 }
在您的情况下,您提供了未初始化的值。取消引用它是未定义的行为。在您的情况下,它导致分段错误。
为了进一步澄清,这也可行
int main(void) {
struct addrinfo *results;
struct addrinfo **results_addr = &results;
getaddrinfo("localhost", "http", NULL, results_addr); // works
return 0;
}
但是上面的例子只是为了说明的目的,它不是通过的双指针而是初始化的问题。只需通过更清晰可读的&result
。
getaddrinfo
函数将为传递的参数指向的指针赋值。在第一种情况下,您直接传递未初始化的局部变量results
的值,因此它并不真正指向任何位置,并且取消引用它会导致未定义的行为(这表现为崩溃)。在第二种情况下,您传递一个指向results
局部变量的指针,如果函数成功,它将指向第一个addrinfo结构。