memset设置字符指针NULL / Garbage

时间:2014-09-29 20:55:49

标签: c sockets memset

以下是我的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->

1 个答案:

答案 0 :(得分:1)

您的指针ip_addrport_nopage都指向char line[512];,它是getClientInput函数的局部变量。在此函数返回后,内存将被释放。

connect_web中出现的症状是因为该内存被重用于connect_web内的局部变量;所以修改那些局部变量意味着你的指针所指向的char line[512]的内容似乎会改变。

要解决此问题,您可以将其设为static char line[512];,或者您可以让getClientInput函数为每个字符串动态分配内存&#34;返回&#34;。

然而,您的代码已经非常混乱且难以理解,因此您遇到内存错误也就不足为奇了。我建议创建一个struct,其中包含您需要的所有指针(而不是具有3个指针的 ad hoc 数组或函数参数列表),并确保分配一个地方的结构实例的所有内容。然后,您可以使用单个函数在完成整个结构后释放它。