以下是我的C程序的一个功能。在下面的函数中,我传递了3个char指针,但我根本没有在函数中使用它们。但是在执行memset()函数之后,字符串的值要么变为NULL,要么变为GARBAGE。谁能让我知道为什么会这样?
这是完整的代码....请忽略错误的编码风格作为我的测试代码:)。
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/poll.h>
static void * process_request_client(void *arg);
void getClientInput(int sockfd, char ** ptr_ip_addr, char ** ptr_port_no, char ** ptr_page);
int split( char * str, char delim, char ***array, int *length );
int connect_web(char * ip_addr, char * port, char * page);
void process_webPage(int soc_client, int soc_web, char * page, char * host);
//##############
int main (int argc, char **argv) {
/* variables section */
pthread_t tid;
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
/* creating a socket */
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n%s: Error in socket", argv[0]);
exit(0);
}
/* configuring server address structure */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9876);
/* binding our socket to the service port */
if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) {
printf("\n%s: Error in bind", argv[0]);
exit(0);
}
/* convert our socket to a listening socket */
if (listen(listenfd, 5) < 0) {
printf("\n%s: Error in listen", argv[0]);
exit(0);
}
for ( ; ; ) {
clilen = sizeof(cliaddr);
/* accept a new connection and return a new socket descriptor to
handle this new client */
if ((connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &clilen)) < 0) {
printf("\n%s: Error in accept", argv[0]);
exit(0);
}
pthread_create(&tid, NULL, &process_request_client, (void *) connfd);
}
return 0;
}
static void * process_request_client(void *soc_client) {
char * ip_addr;
char ** ptr_ip_addr;
char * port_no;
char ** ptr_port_no;
char * page;
char ** ptr_page;
ptr_ip_addr = &ip_addr;
ptr_port_no = &port_no;
ptr_page = &page;
int soc_web;
pthread_detach(pthread_self());
getClientInput((int) soc_client,ptr_ip_addr,ptr_port_no,ptr_page);
printf("ip_addr in process_request_client -> %s \n port in process_request_client-> %s \n page in process_request_client->%s\n",ip_addr,port_no,page);
//create socket connection to web server
soc_web = connect_web(ip_addr, port_no, page);
printf("ip_addr in process_request_client -> %s \n port in process_request_client-> %s \n page in process_request_client->%s\n",ip_addr,port_no,page);
//process webPage
//process_webPage((int)soc_client, soc_web, page, ip_addr);
printf("ip_addr in process_request_client -> %s \n port in process_request_client-> %s \n page in process_request_client->%s\n",ip_addr,port_no,page);
close(soc_web);
close((int) soc_client);
return (NULL);
}
void getClientInput(int sockfd, char ** ptr_ip_addr, char ** ptr_port_no, char ** ptr_page){
ssize_t n;
char line[512];
char **res;
int rc, count = 0, k=0;
/* read from socket */
n = read(sockfd, (void *) line, 512);
if (n < 0) {
printf("\nError in read");
exit(0);
} else if (n == 0) {
return;
}
line[n-1] = NULL;
printf("Yo baby got it:%d\n",n);
//printf("%s\n",line);
//printf("####################################\n");
//split it and store it variables
rc = split( line, ':', &res, &count );
if( rc ) {
printf("Error: error in spliting \n");
}
*ptr_ip_addr = res[0];
*ptr_port_no = res[1];
*ptr_page = res[2];
printf("in getClientInput ->%s \n",*ptr_ip_addr);
printf("in getClientInput ->%s \n",*ptr_port_no);
printf("in getClientInput ->%s \n",*ptr_page);
//close(sockfd); //closed here earlier
}
int split( char * str, char delim, char ***array, int *length ) {
char *p;
char **res;
int count=0;
int k=0;
int index = 0;
do{
//printf("%c\n", str[]);
index++;
} while (str[index] != NULL);
str[index] = ':';
index++;
str[index] = NULL;
printf("%s--------------------------\n",str);
p = str;
// Count occurance of delim in string
while( (p=strchr(p,delim)) != NULL ) {
*p = 0; // Null terminate the deliminator.
p++; // Skip past our new null
count++;
}
// allocate dynamic array
res = calloc( 1, count * sizeof(char *));
if( !res ) return -1;
p = str;
for( k=0; k<count; k++ ){
if( *p ) res[k] = p; // Copy start of string
p = strchr(p, 0 ); // Look for next null
p++; // Start of next string
}
*array = res;
*length = count;
return 0;
}
int connect_web(char * ip_addr_old, char * port_old, char * page_old) {
struct addrinfo hints, *res;
int sockfd, retVal;
char * ip_addr="www.website.edu";
char * port ="80";
printf("11111..ip_addr in connect_web 1 -> %s \n port in connect_web 2-> %s \n page in connect_web 3->%s\n",ip_addr_old,port_old,page_old);
printf("ip_addr in connect_web -> %s \n port in connect_web-> %s \n",ip_addr,port);
printf("size= %d\n",strlen(ip_addr));
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof hints);
printf("2222222.ip_addr in connect_web 1 -> %s \n port in connect_web 2-> %s \n page in connect_web 3->%s\n",ip_addr_old,port_old,page_old);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
retVal=getaddrinfo(ip_addr, port, &hints, &res);
printf("getaddrinfo Return Val is -> %d\n",retVal);
// create a socket:
printf("33333333.ip_addr in connect_web 1 -> %s \n port in connect_web 2-> %s \n page in connect_web 3->%s\n",ip_addr_old,port_old,page_old);
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
/* connecting to the server */
//connect(sockfd, res->ai_addr, res->ai_addrlen);
printf("444444.ip_addr in connect_web 1 -> %s \n port in connect_web 2-> %s \n page in connect_web 3->%s\n",ip_addr_old,port_old,page_old);
if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
printf("\n: Error in connect to web page");
exit(0);
}
printf("55555.ip_addr in connect_web 1 -> %s \n port in connect_web 2-> %s \n page in connect_web 3->%s\n",ip_addr_old,port_old,page_old);
return sockfd;
}
void process_webPage(int soc_client, int soc_web, char * page, char * host){
char arr[200];
char * sendline;
char recvline[4096];
int n,rv;
struct pollfd ufds[2];
printf("\n%s----------in process_webPage\n",page);
printf("\n%s----------in process_webPage\n",host);
//ufds[0].fd = s1;
//ufds[0].events = POLLIN | POLLPRI; // check for normal or out-of-band
ufds[1].fd = soc_web;
ufds[1].events = POLLIN; // check for just normal data
// Prepare the HTTP request
sendline = arr;
strcpy(arr,"GET ");
strcat(arr,page);
strcat(arr," HTTP/1.1\r\nHost:");
strcat(arr,host);
strcat(arr,"\r\n\r\n");
/* send it to server */
printf ("%s\n",sendline);
if (write(soc_web, (const void*) sendline, strlen(sendline)) < 0) {
printf("\n: Error in write to web server socket");
exit(0);
}
// Receive data from Socket
rv = poll(ufds, 2, 3500);
/*while ( rv > 0) {
if (rv == -1) {
perror("poll"); // error occurred in poll()
} else if (rv == 0) {
printf("Timeout occurred! No data after 3.5 seconds.\n");
} else {
if (ufds[1].revents & POLLIN) {
recv(soc_web, recvline, 4096-1, 0);
}
}
//fputs(recvline, stdout);
printf("mmmmmmmmmmmmmmmmmmmm %d", rv);
rv = poll(ufds, 2, 3500);
}*/
printf("@@@@@@@@@@@@ Out Side @@@@@@@@@@@\n");
close(soc_web);
}
这是输出
Yo baby got it:37
www.website.edu:80:/~page/index.html:--------------------------
in getClientInput ->www.website.edu
in getClientInput ->80
in getClientInput ->/~page/index.html
ip_addr in process_request_client -> www.website.edu
port in process_request_client-> 80
page in process_request_client->/~page/index.html
11111..ip_addr in connect_web 1 -> www.website.edu
port in connect_web 2-> 80
page in connect_web 3->/~page/index.html
ip_addr in connect_web -> www.utdallas.edu
port in connect_web-> 80
size= 16
2222222.ip_addr in connect_web 1 -> �q�website.edu
port in connect_web 2-> 80
page in connect_web 3->/
getaddrinfo Return Val is -> 0
33333333.ip_addr in connect_web 1 ->
port in connect_web 2->
page in connect_web 3->
444444.ip_addr in connect_web 1 ->
port in connect_web 2->
page in connect_web 3->
55555.ip_addr in connect_web 1 -> �q�webs�PS�`PS�
port in connect_web 2->
page in connect_web 3->
ip_addr in process_request_client -> �q�webs�PS�`PS�
port in process_request_client->
page in process_request_client->
ip_addr in process_request_client -> �q�webs�PS�`PS�
port in process_request_client->
page in process_request_client->
答案 0 :(得分:1)
您的指针ip_addr
,port_no
,page
都指向char line[512];
,它是getClientInput
函数的局部变量。在此函数返回后,内存将被释放。
connect_web
中出现的症状是因为该内存被重用于connect_web
内的局部变量;所以修改那些局部变量意味着你的指针所指向的char line[512]
的内容似乎会改变。
要解决此问题,您可以将其设为static char line[512];
,或者您可以让getClientInput
函数为每个字符串动态分配内存&#34;返回&#34;。
然而,您的代码已经非常混乱且难以理解,因此您遇到内存错误也就不足为奇了。我建议创建一个struct
,其中包含您需要的所有指针(而不是具有3个指针的 ad hoc 数组或函数参数列表),并确保分配一个地方的结构实例的所有内容。然后,您可以使用单个函数在完成整个结构后释放它。