2016-03-28 4 views
1
#include <netdb.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <netinet/in.h> 

int main(int argc, char** argv) 
{ 
    char *ptr, **pptr; 
    char str[100]; 
    struct hostent *hptr; 
    int  i=0; 

    while(--argc>0) 
    { 
     ptr=*(++argv); 
     if((hptr=gethostbyname(ptr))==NULL) 
     { 
     printf("gethostbyname() error for host: %s: %s", ptr, hstrerror(h_errno)); 
     exit(1); 
     continue; 
     } 

     printf("official hostanme: %s \n", hptr->h_name); 

     for(pptr=hptr->h_aliases; *pptr!=NULL; pptr++) 
     printf("\talias: %s \n", *pptr); 

     switch(hptr->h_addrtype) 
     { 
     case AF_INET: 
     pptr=hptr->h_addr_list; 

     for(; *pptr!=NULL; pptr++) 
      printf("\taddress: %s \n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); 
     break; 

     default: 
     printf("unknown addres type"); 
     break; 
     } 
    } 
    exit(0); 
} 

なぜこのコードは私にセグメンテーションフォールトを与えますか?gethostbyname()セグメンテーションエラー

氏名の出力までは問題ありません。しかしその後、それは私に欠陥を与えます。

このソースコードには構文上の問題はないと思います。それでは何が問題なの?

+2

[POSIX.1-2008は、gethostbyname()、gethostbyaddr()、およびh_errnoの仕様を削除し、代わりにgetaddrinfo(3)とgetnameinfo(3)の使用を推奨しています。](http://linux.die.net/man/3/gethostbyname) – pmg

+1

あなたは、 'h_aliases'が指している' char * 'ポインタがNULLでないことをチェックしています。しかし、 'h_aliases'自体もNULLである可能性があります(つまり、エイリアスはありません)。 – tofro

+2

デバッガ内でコードを実行して、プログラムがクラッシュした正確なコード行を見つけ、実際に何が起こっているかを知るために必要なすべての変数を調べます。 – alk

答えて

2

64ビットプラットフォームであると仮定すると、プロトタイプ化されていないので、コードはinet_ntop()によって返されるポインタ値の32ビットを失います。後者のために、コンパイラはintを返すと仮定していますが、ポインタは64ビットであるため、たぶん32ビット幅しかない可能性があります。

32ビットを失うとポインタの値が無効になります。printf()に渡すと、未定義のビヘイビアが呼び出され、幸いにもプログラムがクラッシュしました。いずれかのこの問題を解決行方不明プロトタイプ追加するには

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 

か、単に適切なヘッダーを含める

#include <arpa/inet.h> 

コンパイラは、ほとんどの場合、このについて警告。そのような警告を深刻に受け、警告が出なくなるまでコードを修正してください。

関連する問題