printf和多个字符串的不良行为

Mic*_* S. 2 c++ printf inet

当我使用带有两个字符串的printf/printf_s时,我得到两个%s变量的相同输出.

IN_ADDR oldIP;
oldIP.S_un.S_addr = iptable[j]->ipAddress;
IN_ADDR newIP;
newIP.S_un.S_addr = adapterTbl->table[i].dwAddr;
printf_s("index %d old: %s new: %s", 
          adapterTbl->table[i].dwIndex, inet_ntoa(oldIP),
           inet_ntoa(newIP));
Run Code Online (Sandbox Code Playgroud)

输出是:

index 11 old: 192.168.1.1 new: 192.168.1.1
Run Code Online (Sandbox Code Playgroud)

现在,我已经通过在print语句之前断开来检查oldip和newip的值是不同的,并且我还尝试使用以下函数并在print语句中使用它(而不是inet_ntoa):

char *convertIP (DWORD ip)  
{  
    IN_ADDR *addr = new IN_ADDR;
    memset(addr, 0, sizeof(IN_ADDR));
    addr->S_un.S_addr = (u_long) ip;
    return inet_ntoa(*addr);
} 
Run Code Online (Sandbox Code Playgroud)

这个输出是:

192.168.1.1
192.168.1.2
index 11 old: 192.168.1.1 new: 192.168.1.1
Run Code Online (Sandbox Code Playgroud)

为什么我会看到这种行为,我该如何解决?
谢谢 :)

Mat*_*Mat 6

inet_ntoa retuns:

静态分配的缓冲区,后续调用覆盖

(这是来自Linux联机帮助页.)

你不能在一个函数中使用它两次,只有第二个调用的输出是可见的(并且你不知道这两个调用中的哪一个是第二个 - 未指定函数参数的评估顺序).

做两个单独的printfs,或将输出复制inet_ntoa到本地缓冲区并输出它们.

来自POSIX:

inet_ntoa()的返回值可能指向可能被后续调用inet_ntoa()覆盖的静态数据.

所以这种行为可能不仅限于Linux,你不能依赖它而不是覆盖静态缓冲区.