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

标签 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;
}

我的代码工作正常。有什么区别?

最佳答案

results 最终会指向一个struct addrinfos 的链表,你可以遍历这个链表得到所有与你传入的地址相匹配的地址第三个参数。函数将使指针指向链表,这就是为什么需要指针的地址。当您传递 struct addrinfo* 变量的地址时,它可以指向列表。取消引用传递的变量将没问题,因为取消引用的值是变量 results 的值。 (这解释了为什么 struct addrinfo *results;&results 有效)。

为什么会出现错误?

它指向链表。在来自 heregetaddrinfo 的源代码中

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

关于c - 使用 getaddrinfo() 指向导致段错误的结构的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47952971/

相关文章:

c - 将指向字符的指针传递给函数

c - 将函数指针设置为静态地址

c - Ubuntu Socket编程: Packets are repackaged between TX and RX

c - 在 C 中的套接字上使用标准 read() 和 write() 调用

c++ - 最佳实践 : Sending typed data over TCP

c - 如果在 BSD 套接字上多次调用 close() 会发生什么

c - 使用函数将节点添加到链表

c++ - 如何在不知道其父节点的情况下旋转子树

c++ - 指向抽象类型的指针数组

c++ - 在 C++11 中使用不带托管共享指针的 shared_from_this()