繁体   English   中英

OSX上的inet_ntoa()分段错误

[英]inet_ntoa() segmentation fault on OSX

我遇到了一个问题,即inet_ntoa会导致OSX上的分段错误,而这在Linux上不会发生。

我的测试代码如下。

// sample.c
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
//#include <arpa/inet.h>  // adding this line prevents the segfault

int main() {
    struct sockaddr_in addr;
    struct sockaddr_in client;

    int sock0 = socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(12345);
    addr.sin_addr.s_addr = INADDR_ANY;

    bind(sock0, (struct sockaddr *)&addr, sizeof(addr));
    listen(sock0, 5);

    while (1) {
        int len = sizeof(client);
        int sock = accept(sock0, (struct sockaddr *)&client, (socklen_t *)&len);
        printf("accepted connection from %s, port=%d\n",
               inet_ntoa(client.sin_addr), ntohs(client.sin_port));
        send(sock, "HELLO", 5, 0);
        close(sock);
    }

    close(sock0);

    return 0;
}

我搜索了一会儿,找到了一个添加了一个包含“arpa / inet.h” 的解决方案 我确认inet_ntoa肯定是在inet.h中声明的,我确信这是正确的方法。

但我无法理解为什么没有它这个代码不起作用。 当我在没有包含行的情况下构建和链接此代码时会发生什么?

我知道构建此代码会显示警告“隐式声明函数”,但不会发生链接错误。 这意味着链接器以某种方式找到了inet_ntoa的实现,我想。 这是错的吗?

谢谢! 任何建议都非常感谢。

我猜你的OSX系统是64位而你的Linux系统是32位。 假定未声明的函数返回整数。 如果64位指针衰减为32位整数,该整数被解除引用为指针,则可能会出现分段错误。

C允许隐式声明函数( C中的隐式函数声明 )。 这就是您没有收到编译器错误的原因。 此外,inet_ntoa位于glibc中,默认情况下由gcc链接,因此链接器会找到函数的定义,因此您不会收到链接器错误。 发生段错误是因为1)C假设,因为它是隐式声明的,函数返回一个int和2)在Mac上inet_ntoa glibc返回一个64位指针,它被转换为32位值并丢失信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM