执行以下操作时,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中, global,最终获得strcpy()
一个IP地址x.x.x.x
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
答案 0 :(得分:4)
我要做的第一件事正在改变:
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);
记住检查分配失败并在不再需要时释放它。
答案 1 :(得分:2)
函数data()
的最后一行是read()
。您正在尝试将数据读入buffer
;你没有为buffer
分配任何存储空间,所以指针(幸运的是)为NULL,导致崩溃。