使用getaddrinfo()指向结构导致段错误的指针

时间:2017-12-23 13:38:23

标签: c sockets pointers struct getaddrinfo

我正在使用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;
}

我的代码工作正常。差异是什么?

2 个答案:

答案 0 :(得分:1)

results最终将指向struct addrinfos的链接列表,您可以浏览此列表以获取与您传入的第三个参数相匹配的所有地址。函数将使指针指向链表,这就是为什么指针的地址是预期的。当您传递struct addrinfo*变量的地址时,可以指向该列表。取消引用传递的变量将是正常的,因为取消引用的值是变量results的值。 (这解释了struct addrinfo *results;&results的原因。

为什么会发生错误?

它指向链表。来自here

getaddrinfo来源
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

答案 1 :(得分:0)

getaddrinfo函数将为传递的参数指向的指针赋值。在第一种情况下,您直接传递未初始化的局部变量results的值,因此它并不真正指向任何位置,并且取消引用它会导致未定义的行为(这表现为崩溃)。在第二种情况下,您将指针传递给results局部变量,如果函数成功,它将指向第一个addrinfo结构。