2016-07-01 13 views
3

以下のプログラムを実行すると、同じIPアドレス出力が表示されます。それは別個のIPを与えると仮定します。printfのシステムコールの出力が異常に動作する

#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の何が問題になっている(GCCコンパイラでのLinuxにしようとしましたか)?しかし、以下のような2つのprintfがある場合、答えは正しいです。

printf("ip_1 = %s\n",inet_ntoa(ip_1)); 
printf("ip_2 = %s\n",inet_ntoa(ip_2)); 

答えて

10

inet_ntoaのドキュメントを読んで、私たちは見つける:

文字列は、後続の呼び出しが上書きされます静的に割り当てられたバッファに返されます。

inet_ntoaを2回コールし、2回目の呼び出しで1回目の呼び出しで返された文字列が上書きされます。

さらに、printf(またはそれに関する他の関数)への関数呼び出しの引数が評価される順序が指定されていないため、inet_ntoaの呼び出しのどれが最初になるのか、それは秒になります。

inet_ntoaは古い関数であり、新しいコードでは使用しないでください。 IP4以外のアドレスファミリは理解できません。スレッドセーフではなく、このような予期しない動作を与える静的バッファを使用します。あなたの標準ライブラリにgetnameinfoがあるかどうかを確認し、その代わりに使用するのが少し難しくなりますが、現在は間違いなく正しいでしょう。

+0

ありがとうございました。明らかになった。はい、静的に割り当てられたバッファが原因です。私はこの動作を次のコードで再現できます。 2番目のものは最初のものを上書きします。 char * fun(char * str) { スタティックchar a [10]; strcpy(a、str); リターンa; } int main() { char * ptr1、* ptr2; ptr1 = fun( "hello"); ptr2 = fun( "world"); printf( "ptr1 =%s \ n"、ptr1); printf( "ptr2 =%s \ n"、ptr2); return 0; } –

+0

@GnanaGuruNatarajan Btw。 2つの関数呼び出しのどちらが最初になるかは不明です。私はいくつかの詳細と私の答えを編集します。 – Art

関連する問題