缺少头文件导致的段错误
冷胜魁(Seaquester)
lengshengkui@gmail.com
2011-9-14
有这样一段简单的代码,在32位Linux(CentOS 6)下没有问题,但是,拿到64位Linux(CentOS 6)下运行就会出现段错误。
-
#include <stdio.h>
-
#include <string.h>
-
#include <netdb.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
-
-
int get_host_ip(const char* server)
-
{
-
struct addrinfo *result = NULL;
-
int ret;
-
struct addrinfo addr;
-
-
memset(&addr, 0, sizeof(addr));
-
addr.ai_socktype = SOCK_STREAM;
-
-
ret = getaddrinfo(server, NULL, &addr, &result);
-
if (ret) {
-
perror("getaddrinfo");
-
return ret;
-
}
-
-
struct addrinfo *pCurr = result;
-
printf("%s:\n", server);
-
for (; pCurr; pCurr = pCurr->ai_next) {
-
printf("%s\n", inet_ntoa(((struct sockaddr_in*)(pCurr->ai_addr))->sin_addr));
-
}
-
printf("\n");
-
-
freeaddrinfo(result);
-
return 0;
-
}
-
-
-
int main()
-
{
-
get_host_ip("localhost");
-
return 0;
-
}
运行结果如下:
-
[shengkui@uranus code]$ ./getaddr
-
chinaunix.net:
-
Segmentation fault (core dumped)
很奇怪,通过gdb来调试了一下:
-
[shengkui@uranus code]$ gcc -g -o getaddr getaddr.c
-
[shengkui@uranus code]$ gdb ./getaddr
-
GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.el6)
-
Copyright (C) 2010 Free Software Foundation, Inc.
-
License GPLv3 : GNU GPL version 3 or later
-
This is free software: you are free to change and redistribute it.
-
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
-
and "show warranty" for details.
-
This GDB was configured as "x86_64-redhat-linux-gnu".
-
For bug reporting instructions, please see:
-
...
-
Reading symbols from /home/shengkui/work/code/getaddr...done.
-
(gdb) run
-
Starting program: /home/shengkui/work/code/getaddr
-
localhost:
-
-
Program received signal SIGSEGV, Segmentation fault.
-
0x000000317a247fe7 in vfprintf () from /lib64/libc.so.6
-
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.x86_64
-
(gdb) bt
-
#0 0x000000317a247fe7 in vfprintf () from /lib64/libc.so.6
-
#1 0x000000317a24ef8a in printf () from /lib64/libc.so.6
-
#2 0x0000000000400736 in get_host_ip (server=0x40088d "localhost") at getaddr.c:28
-
#3 0x0000000000400774 in main () at getaddr.c:40
-
(gdb) f 2
-
#2 0x0000000000400736 in get_host_ip (server=0x40088d "localhost") at getaddr.c:28
-
28 printf("%s\n", inet_ntoa(((struct sockaddr_in*)(pCurr->ai_addr))->sin_addr));
-
(gdb) quit
发现出错在 inet_ntoa 那一行。查看了 inet_ntoa 的帮助,没有发现什么特别的地方。
试着打开编译的warning开关看看有没有什么发现:
-
[shengkui@uranus ~]$ gcc -g -o getaddr getaddr.c -Wall
-
getaddr.c: In function 'get_host_ip':
-
getaddr.c:26: warning: implicit declaration of function 'inet_ntoa'
-
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 需要的头文件加上去:
-
#include
-
#include
-
#include
编译,运行,结果正确,没有段错误!
这个问题提醒我们,函数的声明不是可有可无的,不要小看任何一个warning。
阅读(723) | 评论(0) | 转发(0) |