如果运行以下程序,您将看到相同的IP地址输出。它假设给出不同的IP。 (在Linux中用gcc编译器试过)
#include<stdio.h>
#include <arpa/inet.h>
int main()
{
struct in_addr ip_1, ip_2;
ip_1.s_addr = 0x300a620a;
ip_2.s_addr = 0x117630a;
printf("ip_1 = %s \t ip_2 = %s\n",inet_ntoa(ip_1), inet_ntoa(ip_2));
return 0;
}
这printf
有什么问题?但如果我们在下面有两个printf
,答案是正确的。
printf("ip_1 = %s\n",inet_ntoa(ip_1));
printf("ip_2 = %s\n",inet_ntoa(ip_2));
答案 0 :(得分:10)
阅读inet_ntoa
的文档,我们发现:
该字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。
您对inet_ntoa
进行两次调用,第二次调用将覆盖第一次调用返回的字符串。
此外,未指定函数调用printf
(或任何其他函数)的参数将以何种顺序进行评估,因此您无法真正知道对{{{{}}的调用。 1}}将是第一个,将是第二个。
inet_ntoa
是一个旧函数,不应在新代码中使用。它不了解IP4以外的其他地址族,它不是线程安全的,它使用静态缓冲区来提供这种意外行为。检查你的标准库是否有inet_ntoa
并使用它,它使用起来有点困难,但它现在更加正确,将来肯定会更正确。