When I use printf/printf_s with two strings, I get the same output for both %s vars.
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));
Output is:
index 11 old: 192.168.1.1 new: 192.168.1.1
Now, I have checked that the values of oldip and newip are different by breaking before the print statement, and I have also tried to make the following function and use it in the print statement (instead of 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);
}
The output with this was:
192.168.1.1
192.168.1.2
index 11 old: 192.168.1.1 new: 192.168.1.1
Why am I seeing this behavior, and how can I fix it?
Thanks :)
inet_ntoa
retuns:
a statically allocated buffer, which subsequent calls overwrite
(This is from the Linux manpage.)
You can't use it twice in a function, only the output of the second call will be visible (and you don't know which one of the two calls is the second - order of evaluation of arguments to a function is unspecified).
Do two separate printf
s, or copy the output of inet_ntoa
to local buffers and output those.
From POSIX:
The return value of inet_ntoa() may point to static data that may be overwritten by subsequent calls to inet_ntoa().
So this behavior is probably not limited to Linux, and you can't rely on it not overwriting a static buffer.
For the reasons that Mat described, you must use the result of one call to inet_ntoa
before performing the next call.
Here is one easy way to do that:
IN_ADDR oldIP;
oldIP.S_un.S_addr = iptable[j]->ipAddress;
IN_ADDR newIP;
newIP.S_un.S_addr = adapterTbl->table[i].dwAddr;
std::string s_old(inet_ntoa(oldIP));
std::string s_new(inet_ntoa(newIP));
printf_s("index %d old: %s new: %s",
adapterTbl->table[i].dwIndex, s_old.c_str(),
s_new.c_str());
Note that the string
constructor makes a copy of the passed-in C string. Thus, when inet_ntoa
is invoked again, it is free to overwrite its previously-stored value.