getaddrinfo() 上的段错误

Posted

技术标签:

【中文标题】getaddrinfo() 上的段错误【英文标题】:Seg Fault on getaddrinfo() 【发布时间】:2011-07-19 21:17:01 【问题描述】:

我的 getaddrinfo 调用出现分段错误,无法弄清楚原因。它发生在我的服务器和客户端上。一些代码(服务器端)是 -

class TcpServer 
public:

    TcpServer(int);
    ~TcpServer();

    void launchServer();

    void communicate();

private:
    const char* port;
    int fd;
    int comm_fd;
;

在 tcpserver.cpp-

void TcpServer::launchServer() 
    int status;

    struct addrinfo hints;
    struct addrinfo *servinfo;  //will point to the results

    //store the connecting address and size
    struct sockaddr_storage their_addr;
    socklen_t their_addr_size;

    //socket infoS
    memset(&hints, 0, sizeof hints); //make sure the struct is empty
    hints.ai_family = AF_INET;  //local address
    hints.ai_socktype = SOCK_STREAM; //tcp
    hints.ai_flags = AI_PASSIVE;     //use local-host address

    //get server info, put into servinfo
    if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) 
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    

主要-

TcpServer server(4950);
server.launchServer();

传递给构造函数的int 被强制转换为用于端口的const char*

当我运行 gdb 时,它给了我一个回溯 -

#0  0xb7dca737 in getaddrinfo (name=0x8054824 "127.0.0.1", 
    service=0x1356 <Address 0x1356 out of bounds>, hints=0xbffff20c, 
    pai=0xbffff234) at ../sysdeps/posix/getaddrinfo.c:2080
#1  0x08050f79 in TcpServer::launchServer (this=0xbffff304) at tcpserver.cpp:25
#2  0x0804eae9 in main (argc=1, args=0xbffff3f4) at mainserver.cpp:47

所以“地址 0x1356 越界”让我相信端口有问题,但我不知道可能出了什么问题。如果有人能指出错误,我将不胜感激。感谢您的帮助。

【问题讨论】:

在同一个源文件中混合两种语言很难。我建议您在项目中坚持使用 C 或 C++ 之一。 您对 getaddrinfo 的 port 参数是错误的。你如何初始化你的 TcpServer 类的port 成员? @pmg 他使用 C 是因为他从手册页复制了必要的代码。 @nos:他实际上提到了如何(你是对的,他做错了)。我已将那部分加粗,以便更清楚错误是什么。 @Sterling:正确的代码应该很少有演员表。尽可能避免强制转换,这是您的问题的确切原因。不幸的是,这是许多人在学习指针时似乎养成的习惯:-/. 【参考方案1】:
getaddrinfo("127.0.0.1", port, &hints, &servinfo)
                          ^

那应该是char *。我猜你正在传递一个整数并强制库访问一个无效的地址。

编辑

根据 Blagovest Buyukliev 的评论,我相信您在构造函数中正在做这样的事情:this-&gt;port = (const char*) port

您需要使用一些东西(snprintf 也许?)将该整数转换为char *。简单地投射是不行的

【讨论】:

@Blagovest Buyukliev 我认为它的初始化方式错误(使用= @Blagovest Buyukliev:我已经将他指定如何初始化port 成员的部分加粗(这确实是错误所在)。 @Evan:这是我忽略的一个重要细节 :-) @Evan Teran 确实如此。【参考方案2】:

您是否应该通过引用而不是值传递port,即&amp;port? 0x1356 与 4950 是相同的值,4950 是您尝试使用的端口号。

编辑: 好的,我看到它应该是一个字符串而不是一个指向 int 的指针。我将保留我的答案,因为它表明端口值被错误地解释为地址。

【讨论】:

【参考方案3】:

您正在设置一个指向端口的指针,但没有为其分配内存。 (至少我在你列出的代码中看不到。)

Port 应该是一个字符串(即 char 数组),而不是指向 char 的指针。也不是整数。

【讨论】:

以上是关于getaddrinfo() 上的段错误的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Mail Smtp php_network_getaddresses: getaddrinfo failed: Name or service not known

CHEF 服务器--错误:网络错误:getaddrinfo:提供节点名或服务名,或未知

JNI_CreateJavaVM 上的段错误

相当于 Windows/MSVC 上的段错误?

对 getaddrinfo 的未定义引用

Node.js http.request 失败并显示 [错误:getaddrinfo EADDRINFO]