-1

I have code like this:

char buf[128];
char *data = NULL;
char *temp = NULL;

int full = 0;

int n = 0;

do {
     bzero(buf, sizeof(buf));
     n = recv(newsock, buf, sizeof(buf), 0);

     full += sizeof(buf);

     if(n != 0)
          temp = realloc(data, sizeof(buf));

     if(temp != NULL) {
          data = temp;
     } else {
         // error
     }

     memcpy(data + (full - sizeof(buf)), buf, sizeof(buf));

     printf("%s\n",data);
} while(n > 0);

In this code i try get some data from socket to buffer and put this data into the memory. But i have problem. On third iteration of while cycle i get message like this:

*** glibc detected *** ./server: realloc(): invalid next size: 0x09a4c008 ***

When i remove memcpy() function everything alright, but how can i put data into memory? What is wrong?

amidnikmal
  • 86
  • 3
  • 9

2 Answers2

1

The problem is that you keep adding to data, but you don't expand its memory. The line

temp = realloc(data, sizeof(buf));

always allocates 128 bytes. You need to update that that in every iteration it will allocate more. Maybe you intended to do this insead:

temp = realloc(data, full);

?

Israel Unterman
  • 13,158
  • 4
  • 28
  • 35
1

I would use something more like this:

char buf[128];
char *data = NULL;
char *temp = NULL;
int n, datalen = 0, datacap = 0;

do
{
    n = recv(newsock, buf, sizeof(buf), 0);
    if (n < 0)
    {
        if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
        {
            // error
            break;
        }

        fd_set fdr;
        FD_ZERO(&fdr);
        FD_SET(nwsock, &fdr);

        struct timeval to;
        to.tv_sec = 5;
        to.tv_usec = 0;

        n = select(newsock+1, &fdr, NULL, NULL, &to);
        if (n <= 0)
        {
            // error/timeout
            break;
        }

        continue;
    }

    if (n == 0)
    {
        // disconnected
        break;
    }

    if ((datalen + n) > datacap)
    {
        datacap = ((datalen + n) + (sizeof(buf)-1)) & ~(sizeof(buf)-1);
        // or:
        // datacap = (((datalen + n) + sizeof(buf)) / sizeof(buf)) * sizeof(buf);

        temp = realloc(data, datacap);
        if (temp == NULL)
        {
            // error
            break;
        }

        data = temp;
    }

    memcpy(data + datalen, buf, n);
    datalen += n;

    printf("%*.*s", n, n, buf);
}
while (1);
...
if (data) free(data);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • select() return the number of file descriptors. Why do you use this value for analysis below? And what does means this line: `datacap = ((datalen + n) + (sizeof(buf)-1)) & ~(sizeof(buf)-1);` – amidnikmal Sep 24 '13 at 19:09
  • `select()` returns -1 if an error occurs, 0 if the timeout elapses, and >0 if any of the descriptors are signaled. Since only 1 descriptor is being passed in, a return of >0 means that socket became readable within 5 seconds so call `recvfrom()` again, and anything else means the socket is not readable so stop trying. As for the `datacap` calculation, it is taking the sum of `datalen+n` (the data already in the buffer and the new data that was read) and rounding it up to the next highest even multiple of `sizeof(buf)`. – Remy Lebeau Sep 24 '13 at 19:17