printf中系统调用的输出行为奇怪

时间:2016-07-01 10:38:44

标签: c

如果运行以下程序,您将看到相同的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));

1 个答案:

答案 0 :(得分:10)

阅读inet_ntoa的文档,我们发现:

  

该字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。

您对inet_ntoa进行两次调用,第二次调用将覆盖第一次调用返回的字符串。

此外,未指定函数调用printf(或任何其他函数)的参数将以何种顺序进行评估,因此您无法真正知道对{{{{}}的调用。 1}}将是第一个,将是第二个。

inet_ntoa是一个旧函数,不应在新代码中使用。它不了解IP4以外的其他地址族,它不是线程安全的,它使用静态缓冲区来提供这种意外行为。检查你的标准库是否有inet_ntoa并使用它,它使用起来有点困难,但它现在更加正确,将来肯定会更正确。