Search code examples
crecvrealloc

realloc()ing memory for a buffer used in recv()


I need to recv() data from a socket and store it into a buffer, but I need to make sure get all of the data so I have things in a loop. So to makes sure I don't run out of room in my buffer, I'm trying to use realloc to resize the memory allocated to the buffer. So far I have:

 // receive response
 int i = 0;
 int amntRecvd = 0;
 char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
 while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
  i += amntRecvd;
  realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
 }

However, this doesn't seem to be working properly since Valgrind is complaining "valgrind: the 'impossible' happened:". Any advice as to how this should be done properly?

Thanks, Hristo

update... I realized I was using realloc incorrectly. Here is a revised version:

 int i = 0;
 int amntRecvd = 0;
 char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
 while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
  i += amntRecvd;
  char *temp = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
  if (temp != NULL) {
   pageContentBuffer = temp;
  }
 }

However, valgrind still is complaining:

==25812== Syscall param socketcall.recvfrom(buf) points to unaddressable byte(s)
==25812==    at 0x33B880DAA1: recv (in /lib64/libpthread-2.5.so)
==25812==    by 0x401D78: tunnelURL (proxy.c:371)
==25812==    by 0x40142A: client_thread (proxy.c:194)
==25812==    by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812==    by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
==25812==  Address 0x5642768 is 0 bytes after a block of size 4,104 alloc'd
==25812==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==25812==    by 0x401D47: tunnelURL (proxy.c:373)
==25812==    by 0x40142A: client_thread (proxy.c:194)
==25812==    by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812==    by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)

Solution

  • Look up realloc.

    sizeof is a compile time value, not runtime.

    It is possible for realloc to return 0.

    Try this...

    // receive response
    int i = 0;
    int amntRecvd = 0;
    int currentSize = 4096;
    int oldSize = currentSize;
    char *pageContentBuffer = (char*) malloc(currentSize);
    while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
        i += amntRecvd;
        oldSize = currentSize; 
        currentSize += 4096; 
        char *newBuffer = malloc(currentSize); 
        memcpy(newBuffer,pageContentBuffer,oldSize); 
        free(pageContentBuffer); 
        pageContentBuffer = newBuffer;
    }
    

    Your best bet is to reallocate, copy and then free the memory explicitly -- realloc is quirky.