临时C字符串具有相同的地址

时间:2013-09-30 05:35:05

标签: c gdb

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

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包含不同的值。

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:2)

来自inet_ntoa docs

“应用程序不应该对内存的分配方式做任何假设。返回的字符串保证只有在同一个线程中进行下一个Windows套接字函数调用之后才有效。”

它似乎只使用静态缓冲区。因此,您需要在下次调用之前将结果复制到新缓冲区。