Есть ли причина, по которой этот вызов функции не должен работать? - PullRequest
0 голосов
/ 10 февраля 2011

При выполнении следующего, 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

Видите ли вы причину, по которой это может произойти?

global в control.c, в конечном итоге получает strcpy() IP-адрес xxxx

char passive_ip[25] = ""; 

, вызываемый в 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

Ответы [ 2 ]

4 голосов
/ 10 февраля 2011

Меняется первая вещь, которую я буду делать:

char hostname[15];

до:

char hostname[16];

Возможно, вы переполняете буфер, что может привести к повреждению стека. Для полного адреса IPv4 требуется 16 символов: 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);

не забудьте проверить наличие ошибок выделения и освободить его, когда он больше не требуется.

2 голосов
/ 10 февраля 2011

Последняя строка функции data() - это read(). Вы пытаетесь прочитать данные в buffer; вы не выделили хранилище для buffer, поэтому указатель (к счастью для вас) равен NULL, что приводит к сбою.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...