缺少头文件导致的段错误

冷胜魁(Seaquester)
lengshengkui@gmail.com
2011-9-14

有这样一段简单的代码,在32位Linux(CentOS 6)下没有问题,但是,拿到64位Linux(CentOS 6)下运行就会出现段错误。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <netdb.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>


  6. int get_host_ip(const char* server)
  7. {
  8.     struct addrinfo *result = NULL;
  9.     int ret;
  10.     struct addrinfo addr;

  11.     memset(&addr, 0, sizeof(addr));
  12.     addr.ai_socktype = SOCK_STREAM;

  13.     ret = getaddrinfo(server, NULL, &addr, &result);
  14.     if (ret) {
  15.         perror("getaddrinfo");
  16.         return ret;
  17.     }

  18.     struct addrinfo *pCurr = result;
  19.     printf("%s:\n", server);
  20.     for (; pCurr; pCurr = pCurr->ai_next) {
  21.         printf("%s\n", inet_ntoa(((struct sockaddr_in*)(pCurr->ai_addr))->sin_addr));
  22.     }
  23.     printf("\n");

  24.     freeaddrinfo(result);
  25.     return 0;
  26. }


  27. int main()
  28. {
  29.     get_host_ip("localhost");
  30.     return 0;
  31. }

运行结果如下:

  1. [shengkui@uranus code]$ ./getaddr
  2. chinaunix.net:
  3. Segmentation fault (core dumped)
很奇怪,通过gdb来调试了一下:

  1. [shengkui@uranus code]$ gcc -g -o getaddr getaddr.c
  2. [shengkui@uranus code]$ gdb ./getaddr
  3. GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.el6)
  4. Copyright (C) 2010 Free Software Foundation, Inc.
  5. License GPLv3 : GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  6. This is free software: you are free to change and redistribute it.
  7. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  8. and "show warranty" for details.
  9. This GDB was configured as "x86_64-redhat-linux-gnu".
  10. For bug reporting instructions, please see:
  11. <http://www.gnu.org/software/gdb/bugs/>...
  12. Reading symbols from /home/shengkui/work/code/getaddr...done.
  13. (gdb) run
  14. Starting program: /home/shengkui/work/code/getaddr
  15. localhost:
  16. Program received signal SIGSEGV, Segmentation fault.
  17. 0x000000317a247fe7 in vfprintf () from /lib64/libc.so.6
  18. Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.x86_64
  19. (gdb) bt
  20. #0 0x000000317a247fe7 in vfprintf () from /lib64/libc.so.6
  21. #1 0x000000317a24ef8a in printf () from /lib64/libc.so.6
  22. #2 0x0000000000400736 in get_host_ip (server=0x40088d "localhost") at getaddr.c:28
  23. #3 0x0000000000400774 in main () at getaddr.c:40
  24. (gdb) f 2
  25. #2 0x0000000000400736 in get_host_ip (server=0x40088d "localhost") at getaddr.c:28
  26. 28 printf("%s\n", inet_ntoa(((struct sockaddr_in*)(pCurr->ai_addr))->sin_addr));
  27. (gdb) quit
发现出错在 inet_ntoa 那一行。查看了 inet_ntoa 的帮助,没有发现什么特别的地方。
试着打开编译的warning开关看看有没有什么发现:

  1. [shengkui@uranus ~]$ gcc -g -o getaddr getaddr.c -Wall
  2. getaddr.c: In function 'get_host_ip':
  3. getaddr.c:26: warning: implicit declaration of function 'inet_ntoa'
  4. getaddr.c:26: warning: format '%s' expects type 'char *', but argument 2 has type 'int'
inet_ntoa 没有声明,是因为没有加必须的头文件。
inet_ntoa 的返回值是 “char *”, 而编译器似乎把它的返回值当成了int?是这个导致的错误吗?
在64位的Linux 下,int是32位的,而指针(在这里是 char *)是64位的。问题应该就是出在这里!

我把 inet_ntoa 需要的头文件加上去:
  1. #include <sys/socket.h>
  2. #include <netinet/in.h>
  3. #include <arpa/inet.h>
编译,运行,结果正确,没有段错误!

这个问题提醒我们,函数的声明不是可有可无的,不要小看任何一个warning。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值