2011-02-10 14 views
0

以下を実行すると、GDBはそれがdata()の最後の行で失敗だと言う:この関数呼び出しがうまくいかない理由はありますか?

Program received signal EXC_BAD_ACCESS, Could not access memory. 
Reason: 13 at address: 0x0000000000000000 
0x00000001000021ee in data (srvr=Cannot access memory at address 0x6567612d726572fd 
) at /Users/Documents/w11/cs176b/mftp/data.c:121

は、あなたがそれが失敗する理由はどのような理由を参照していますか?

グローバルcontrol.cで、最終的にstrcpy()はcontrol.c

data(passive_ip, passive_port); 

data.c

void data(char* srvr, int prt) { 
    printf("In Data: connecting to %s:%i", srvr, prt); 

    struct hostent *hp = gethostbyname(srvr); 

    if (hp == NULL) { 
     printf("gethostbyname() failed\n"); 
    } else { 
     printf("%s = ", hp->h_name); 
     unsigned int i=0; 
     // while (hp -> h_addr_list[i] != NULL) { 
     printf("%i %s ",i, inet_ntoa(*(struct in_addr*)(hp -> h_addr_list[0]))); 
     //  i++; 
     // } 
     printf("\n"); 
    } 

    char hostname[15]; 
    strcpy(hostname, inet_ntoa(*(struct in_addr*)(hp -> h_addr_list[0]))); 


    int sockfd; 
    int len; 
    struct sockaddr_in address; 
    int result; 
    char* buffer; 


    /* Create a socket for the client. */ 
    sockfd = socket(PF_INET, SOCK_STREAM, 0); 

    /* Name the socket, as agreed with the server. */ 
    address.sin_family = AF_INET; 
    address.sin_addr.s_addr = inet_addr( hostname ); 
    address.sin_port = htons(prt); 
    len = sizeof(address); 

    /* Now connect our socket to the server's socket. */ 
    result = connect(sockfd, (struct sockaddr *)&address, len); 

    if(result == -1) { 
     perror("oops (data): client3"); 
     exit(1); 
    } 

    read(sockfd, buffer, MY_BUFFER_SIZE); 


} // this is line 121 
+0

多分 'データ()'関数がスタック –

+0

を胸像ようGDBは、それがデータの最後の行で失敗だと言うサウンド:理由:アドレスの13:データ内0x0000000000000000 0x00000001000021ee(SRVRは=アドレスのメモリにアクセスできませんが を0x6567612d726572fd) /Users/brian/Documents/w11/cs176b/mftp/data.c:121 ... "srvr"は関数のパラメータです... hmmm –

+1

あなたが投稿したコードは確かにありません問題の診断に役立ちます。最初の反復で失敗した場合は、data()内にあることは間違いありません。 –

答えて

4

内と呼ばれるIPアドレスxxxxの

char passive_ip[25] = ""; 

をD」取得最初に私がやっていることが変わる:

char hostname[15]; 

char hostname[16]; 

あなたも、スタックの破損を引き起こすことになる、バッファをオーバーフローすることができます。完全なIPv4アドレスには、文字:nnn.nnn.nnn.nnnと終端記号\0が必要です。実際には、おそらくIPv6を扱うのに少しだけ興味があるなら、それらの呼び出しを使用すべきではないでしょう。私は、彼らがその世界でうまく動作しないことは確かです。しかしそれは別の問題です。


あなたが持っている(これはほぼ確実にあなたのクラッシュの原因である)の問題は、あなたが行うことです。なし

char *buffer; 
: 
read(sockfd, buffer, MY_BUFFER_SIZE); 

ように実際には、そのバッファにメモリを割り当てますbufferは任意の場所を指します。次のいずれかを使用します

char buffer[MY_BUFFER_SIZE]; 

か:

char *buffer = malloc (MY_BUFFER_SIZE); 

割り当ての失敗を確認するために覚えておくと自由、それはもはや必要ないとき。

+0

len = 13 ..それはIPv4なので、(ヌル終了文字がない限り、適合するはずですが、IP XXX.XXX.XX.XX、== 13文字のようには見えません)。私はそれを16にして保存します。それは良い観察です。 –

+0

勝利。ありがとうございました。 –

+0

私は、人々が自分自身を見つけるために最も基本的な努力をするのではなく、バグを発見するためにここに来るので、SOが平均コード品質の低下にさらに貢献することを心配しています。 –

2

data()の最後の行はread()です。データをbufferに読み込もうとしています。あなたはbufferのためのストレージを割り当てていないので、ポインタは(幸いあなたのために)NULLになり、クラッシュに至ります。

関連する問題