linux tcp 编程中头文件引用导致的惨案

本文记录了作者在Ubuntu环境下使用inet_ntoa函数遇到的Segmentation fault问题及解决方案。作者通过逐步排查,最终发现缺少必要的头文件是引发问题的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在linux下编写了一个 多线程的 tcp server 的 demo,发现了一个奇怪的问题。

我在使用  char *inet_ntoa(struct in_addr in);  这个方法时,编译时出现一个警告,执行的时候程序崩溃,莫名其妙,检查半天,没有发现问题,网上查找,别人都是这么用的。

inet_addr.c:26:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
  printf("%s\n", inet_ntoa(addr));
  ^

调试后发现是调用inet_ntoa() 函数造成的 Segmentation fault (core dumped)


查看函数说明, man inet_ntoa  显示该函数的原型为: char *inet_ntoa(struct in_addr in); 说明如下。

 The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string  in  IPv4  dotted-decimal notation.  The string is returned in a statically allocated buffer, which subsequent calls will overwrite.

说明里给出了一段关于该函数的用法的 代码,如下所示:

#define _BSD_SOURCE
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
   struct in_addr addr;

   if (argc != 2) {
       fprintf(stderr, "%s <dotted-address>\n", argv[0]);
       exit(EXIT_FAILURE);
   }

   if (inet_aton(argv[1], &addr) == 0) {
       perror("inet_aton");
       exit(EXIT_FAILURE);
   }

   printf("%s\n", inet_ntoa(addr));
   exit(EXIT_SUCCESS);
}
决定测试这段代码,编译,没有错误,也没有警告,运行

./inet_addr 192.168.1.1

输出结果

192.168.1.1

一切正常,非常疑惑,然后开始检查两个程序的区别,发现不是用法问题,最后检查头问题,发现我的程序里面没有 include  <arpa/inet.h> 这个头文件,试着在上面的代码中注释掉第二行的头文件,发现出现一样的警告,执行也出现 segmentation fault,看来是头文件问题。

我的使用系统是 ubuntu 14.04,gcc version 4.8.2,安装了很多编译工具。

然后我换用另外一台 ubuntu 12.04系统的机子,gcc version  4.6.3, 重复上面的过程,发现注释掉 arpa/inet.h 头文件后,编译无法通过,提示:

error: storage size of ‘addr’ isn’t known
搞了半天是我系统环境问题,导致我没有引用 inet.h这个头文件也编译通过了,只是给出一个警告。还没查到具体是哪个地方的原因。

补充:

查找头文件,在 inet.h中定义了 

typedef uint32_t in_addr_t;
struct in_addr{
        in_addr_t s_addr;
}
实际上 in_addr 为 32位无符号整数,unsigned int ,修改代码,自己声明这个结构体,注释掉所有头文件,赋值addr.s_addr = 16885952, 这是之前用 192.168.1.1转换过来的,发现程序还是能编译通过,运行时出现 segmentation fault。问题原因依旧没有找到。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值