Multiple Malloc Calls on one Variable

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tech1544
    New Member
    • Feb 2013
    • 3

    Multiple Malloc Calls on one Variable

    I'd like to know what happens if I use multiple calls to malloc() on one pointer (without free) in a single function. Here is the example:

    Code:
    void *data_thread(void *sockfd_ptr) {
      int sockfd = *(int *) sockfd_ptr;
      const int BUFSIZE = 5;
      char recvmessage[BUFSIZE];
      char *headerstr = NULL;
      char *newheaderstr = NULL;
      int recvbytes = 0;
      int curheadlen = 0;
      int totalheadlen = 0;
      httpreq_t req;
      int statcode = 200;
      int done = 0;
      int seen_header = 0;
      char *header_end;
      int content_length = 0;
      char *qstr;
    
      free(sockfd_ptr); // we have the int value out of this now
      recvmessage[BUFSIZE - 1] = '\0'; // mark end of "string"
    
      
      /* Read incoming client message from the socket */  
      while(!done && (recvbytes = recv(sockfd, recvmessage, BUFSIZE - 1, 0))) {
        if (recvbytes < 0) {
          perror("recv");
          pthread_exit(NULL);
        }
    	
        recvmessage[recvbytes] = '\0';
    		
        if (seen_header) {
          // getting the entity body
          content_length -= recvbytes;
          if (content_length <= 0) done = 1;
    
        } else {			
          newheaderstr = (char *) malloc((totalheadlen + recvbytes + 1) * sizeof(char));
          newheaderstr[totalheadlen + recvbytes] = '\0';
          memcpy(newheaderstr, headerstr, totalheadlen);
          memcpy(newheaderstr + totalheadlen, recvmessage, recvbytes);
          if (headerstr) free(headerstr);
          headerstr = newheaderstr;
          totalheadlen += recvbytes;
    
          header_end = strstr(headerstr, "\r\n\r\n");
    
          if (header_end) {
    	seen_header = 1;
    	header_end[2] = '\0';
    
    	if (parsereq(&req, headerstr) != 0) {
    	  statcode = 400;
    	}
    
    	if (strcmp(req.method, "POST") == 0) {
    	  // grab the body length
    	  char *clenstr = get_header(&req, "Content-Length");
    
    	  if (clenstr) {
    	    content_length = atoi(clenstr) - ((headerstr + totalheadlen) - header_end - 4);
    	    if (content_length <= 0) done = 1;
    	    free(clenstr);
    
    	  } else {
    	    statcode = 400; // bad request -- no content length
    	    done = 1;
    	  }
    
    	} else {
    	  // This isn't a POST, so there's no entity body
    	  done = 1;
    	  
    	  if (strcmp(req.method, "GET") != 0
    	      && strcmp(req.method, "HEAD") != 0) {
    	    statcode = 501; // unknown request method
    	  }
    	}
          }
        }
      } // end of recv while loop
    
    	// used to deref a NULL pointer here... :(
    	if (headerstr != NULL) {
    		  printf("%s\n", headerstr);
    	          free(headerstr);
    
    	}
    
    	send_response(sockfd, &req, statcode);
    	close(sockfd);
     
    
      return NULL;
    }
    So, I'm curious as to what happens with newheaderstr every time malloc() is called. There isn't a realloc() or anything. So what is happening? I didn't think it looked right to keep using malloc() like that.
    Last edited by Rabbit; Feb 13 '13, 10:06 PM. Reason: Please use code tags when posting code.
  • tech1544
    New Member
    • Feb 2013
    • 3

    #2
    Wait, timeout. I think I know what I overlooked here. Since headerstr gets assigned to newheaderstr at one point, it eventually does get freed. So I'm assuming that when malloc is called again for newheaderstr, it must get reassigned to a new memory address. While headerstr is still pointing to the old one. Good, I don't think theres a memory leak here. Although, if you see one let me know. I'd like to know if there's any buffer overflows.

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      When you call malloc you receive the address of the allocation. You use that address to free the allocation. If you don't free, the available memory for your program has gone down. Keep doing it and sooner or later you crash because your available memory has drained away. That's why failing free an allocation is called a memory leak.

      Reusing the pointer to a malloc allocation without a free is a memory leak.

      The compiler won't tell you about this. The rule is he who allocates is he who frees.
      Last edited by weaknessforcats; Feb 14 '13, 07:05 AM. Reason: typo

      Comment

      • tech1544
        New Member
        • Feb 2013
        • 3

        #4
        Thank you for the answer. I do appreciate it. Its crazy how I couldn't find a simple explanation online. Obviously its out there, I just didn't have the right search parameters. Thanks again.

        Comment

        • johny10151981
          Top Contributor
          • Jan 2010
          • 1059

          #5
          Here is a crazy example of memory leak. use this example with you own risk.

          Code:
          int main()
          {
           char *ch;
          
           while(1) //never ending loop
           {
             ch=malloc(1024*1024);
             delay(1000);
           }
           return 0;
          }
          if you run this example, you will see on TaskManager(if you are using windows) that your memory is increasing gradually. you can kill the application from taskmanager or you simply can stop debugging.

          Comment

          Working...