由于某种原因valgrind
不断抛出以下错误:
==6263== Invalid read of size 4
==6263== at 0x40151B9: (within /lib/ld-2.7.so)
==6263== by 0x4005C29: (within /lib/ld-2.7.so)
==6263== by 0x4007A47: (within /lib/ld-2.7.so)
==6263== by 0x40114F3: (within /lib/ld-2.7.so)
==6263== by 0x400D585: (within /lib/ld-2.7.so)
==6263== by 0x4010F0D: (within /lib/ld-2.7.so)
==6263== by 0x4141391: (within /lib/tls/i686/cmov/libc-2.7.so)
==6263== by 0x400D585: (within /lib/ld-2.7.so)
==6263== by 0x4141554: __libc_dlopen_mode (in /lib/tls/i686/cmov/libc-2.7.so)
==6263== by 0x411B286: __nss_lookup_function (in /lib/tls/i686/cmov/libc-2.7.so)
==6263== by 0x411B39F: (within /lib/tls/i686/cmov/libc-2.7.so)
==6263== by 0x411CFC5: __nss_hosts_lookup (in /lib/tls/i686/cmov/libc-2.7.so)
==6263== Address 0x4183d24 is 36 bytes inside a block of size 37 alloc'd
==6263== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
这是我正在做的方式。出现这种情况的原因是什么?感谢
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
char *IPtoHostname(const char *ipaddress)
{
struct hostent *host;
unsigned int ip = 0;
ip = inet_addr (ipaddress);
host = gethostbyaddr ((char *) &ip, sizeof (unsigned int), AF_INET);
if (host == NULL) return NULL;
return strdup(host->h_name);
}
int main () {
const char *ip = "65.55.4.170";
char *a = NULL;
a = IPtoHostname(ip);
printf ("%s\n", a);
free (a);
return 0;
}
更新:当我在Linux hardy 2.6.24-16-generic
下运行它时会发生这种情况Ubuntu 9.10
下不会发生
答案 0 :(得分:2)
您的代码没问题(尽管您应该使用in_addr_t
代替unsigned int
来代替ip
中的变量IPtoHostname()
。
Valgrind报告是well-known issue - 要么是误报,要么是glibc中的错误。
答案 1 :(得分:1)
消除这些遗留功能中的问题的一种方法是停止使用它们。截至2008年,gethostbyname
和gethostbyaddr
已从POSIX移除;他们在IPv6支持,线程安全,不明确的规范和跨平台的不一致实现等方面存在严重问题。你根本就不应该使用它们。
现代替代品是getaddrinfo
和getnameinfo
。如果你使用这些函数,你将永远不必像你一样编写丑陋的包装器。
答案 2 :(得分:0)
inet_addr
并不总是返回简单的unsigned int
。它返回一个in_addr_t
(或in_addr
,具体取决于你的C头的味道,我的linux 2.6.31 / glib 2.0)。在我的系统上,in_addr_t
实际上是128位(16字节),因为inet_addr
可以返回IPv6地址。
同样,gethostbyaddr
需要in_addr_t
,而不是unsigned int
。这几乎肯定是你的问题。将ip
的类型更改为inet_addr_t
并更改相应的sizeof
,并在下次更加关注编译器警告。
struct hostent *host;
in_addr_t ip = inet_addr(ipaddress);
host = gethostbyaddr (&ip, sizeof(ip), AF_INET);
if (host == NULL) return NULL;
return strdup(host->h_name);
答案 3 :(得分:-1)
您没有检查gethostbyaddr
的返回值。
如果它返回 NULL 表示它无法获取主机名怎么办?
在这种情况下,您尝试取消引用 NULL 以致电strdup
上的host->h_name
。
那显然会失败。