简体   繁体   English

inet_ntoa的奇怪printf行为

[英]Weird printf behaviour with inet_ntoa

#include <sys/socket.h>
#include <err.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char **argv) {

    struct sockaddr_in X = {0};
    X.sin_family = AF_INET;
    X.sin_addr.s_addr = inet_addr("127.0.0.1");
    X.sin_port = htons(8080);

    struct sockaddr_in Y = {0};
    Y.sin_family = AF_INET;
    Y.sin_addr.s_addr = inet_addr("212.43.159.20");
    Y.sin_port = htons(80);

    printf("X:Y %s:%s\n", inet_ntoa(X.sin_addr), inet_ntoa(Y.sin_addr));
    printf("X %s\n", inet_ntoa(X.sin_addr));
    printf("Y %s\n", inet_ntoa(Y.sin_addr));

    return 0;
}

Why does first pritnf print same IP twice rather than whats given? 为什么首先pritnf打印两次相同的IP,而不是给出两次? Second and third seem to be okay. 第二和第三似乎还可以。 Seems to happend on linux gcc/clang and freebsd clang, is this is something known? 似乎在Linux gcc / clang和freebsd clang上发生过,这是已知的吗?

From the man page for inet_ntoa : inet_ntoa的手册页中:

The inet_ntoa() function converts the Internet host address in given in network byte order to a string in standard numbers-and-dots notation. inet_ntoa()函数inet_ntoa()网络字节顺序给定的Internet主机地址转换为标准的数字符号形式的字符串。 The string is returned in a statically allocated buffer, which subsequent calls will overwrite. 该字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。

Since inet_ntoa uses a static buffer for its output, and because you call it twice in one function call, printf gets passed two copies of the same pointer. 由于inet_ntoa将静态缓冲区用于其输出,并且由于您在一个函数调用中两次调用了它,所以printf传递了相同指针的两个副本。 It contains the contents of whichever call was done last. 它包含最后一次调用的内容。

You need to split the printing into two separate calls, like you do in the following lines. 您需要像下面几行那样将打印分为两个单独的调用。

Take a look at the POSIX docs for inet_ntoa , notable the "Application Usage" section: 看一下inet_ntoa的POSIX文档,特别是“应用程序用法”部分:

The return value of inet_ntoa() may point to static data that may be overwritten by subsequent calls to inet_ntoa() . inet_ntoa()的返回值可能指向静态数据,该静态数据可能会被随后inet_ntoa() 调用覆盖

This is what is happening here: one of the two calls in your first printf is overwriting what the other did (and you don't know which one - order of evaluation of function arguments is implementation defined). 这就是这里发生的情况:第一个printf中的两个调用之一正在覆盖另一个调用(并且您不知道哪个-函数参数的求值顺序是实现定义的)。

So either stick with two printfs, or copy the string returned by inet_ntoa into your own buffers and then print them. 因此,要么坚持使用两个printfs,要么将inet_ntoa返回的字符串复制到您自己的缓冲区中,然后进行打印。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM