2013-09-30 31 views
1

这两行在gdb中产生以下输出。请注意,两个临时字符串first_strsecond_str的地址具有相同的地址。这是为什么?临时C字符串具有相同的地址

char *first_str = inet_ntoa(first->dest); 
char *second_str = inet_ntoa(second->dest); 


(gdb) p first_str 
$3 = 0x7ffff7ff06d8 "54.208.71.98" 
(gdb) p second_str 
$4 = 0x7ffff7ff06d8 "54.208.71.98" 

first->destsecond->dest包含不同的值。

+1

这是因为这些函数不可重入,inet_ntoa使用静态或全局内部缓冲区。你应该使用inet_ntop。 – goji

+0

确实'inet_ntoa'承诺不这样做?也许你必须解决 –

回答

8

inet_ntoa为其实现使用了一个静态缓冲区,所以基本上每个调用都将ascii ip地址写入同一个地方。请看下图:

https://www.opensource.apple.com/source/Libc/Libc-167/net.subproj/inet_ntoa.c

char * 
inet_ntoa(in) 
    struct in_addr in; 
{ 
    static char b[18]; 
    register char *p; 

    p = (char *)∈ 
#define UC(b) (((int)b)&0xff) 
    (void)snprintf(b, sizeof(b), 
     "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); 
    return (b); 
} 

您应该使用inet_ntop

inet_ntop还具有支持IPv6的附加好处,任何新编写的代码真的应该支持IPv6。 inet_ntop的

用法:

char ip[INET_ADDRSTRLEN]; 
if (!inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip))) { 
    /// do something with error 
} 
2

inet_ntoadocs

“应用程序不应该对其中的内存分配的方式做任何假设返回保证的字符串是有效的直到下一个Windows套接字函数调用在同一个线程中完成。“

它似乎只是使用一个静态缓冲区。所以你需要在下次调用之前将结果复制到新的缓冲区。

相关问题