3

I want to reserve dynamic memory from a socket. The size of the response is variable so I want to use realloc to allocate the proper memory size.

This is the code snippet that takes care of it:

char *ptr = (char*)calloc(sizeof(char),1024);
char *ptr2 = (char*)calloc(sizeof(char),1024);
//printf("aaaaaaa  %p bbbbbbbb",ptr);
int nDataLength;
int i = 0;
while ((nDataLength = recv(Socket, ptr, 1024, 0)) > 0){

    if (i > 0){//prepare in case that the response is bigger than 1024 bytes
        printf("Data len: %d\n", nDataLength);
        printf("%p points toa %d len: %d\n", ptr, *ptr, ((1024 * i) + nDataLength));
        ptr2 = (char*)realloc(ptr2,((1024*i)+nDataLength));
        printf("%p pints toa %d\n", ptr2, *ptr2);
        system("pause");
        memcpy(ptr2, ptr, nDataLength);
    }
    memcpy(ptr2, ptr, nDataLength);
    i++;
}

The problem is that the buffer that I receive from the socket is allways being memcpyed to the same address so I am overwriting the previous buffer. How can I move ptr2 to not overwrite the previous store buffer? It must be somethin like:

memcpy(ptr2+((1024 * i), ptr, nDataLength); but it does not work.

Thank you

Alberto
  • 701
  • 4
  • 9
  • 25

2 Answers2

2

First:

  1. Please don't cast the return value of calloc() in C. Or malloc().
  2. Don't use sizeof (char) to "scale" allocations, it's always just 1 so it's pointless.
  3. There's no need to use calloc() if you're going to recv() into the memory anyway.

Your problem is that you keep passing recv() the start of your growing buffer, instead of the next free location to store at. You should have something like put + nTotalLength as the target for recv(), and then do nTotalLength += nDataLength after each successful reception.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • 1- If I remove the (char*) before calloc I get this error: `cannot convert from 'void *' to 'char *'` 2- I use it to do it compiler independant because char en c has not the same length than in c++ 3- I guess that I need to reserve some memory for the buffer that I am going to receive right? 4- It can be done in the way that you say or in my way. It's the same. The problem is that I dont know how to sum a value (1024) to a pointer. How can I do it? Thanks!!! – Alberto Apr 04 '14 at 07:31
  • I didn't realize you wanted to program in C and C++ at the same time. I wouldn't have answered if I had. :) (Your tagging says "C"). – unwind Apr 04 '14 at 07:37
  • No problem. But, how can I sum an address to a value? So the address returned by calloc and a value like 1024? Thanks – Alberto Apr 04 '14 at 08:15
  • `put + nTotalLength` adds an offset (an integer value) to a pointer. – unwind Apr 04 '14 at 08:20
2

&ptr[1024] gives the address after ptr ends. You just have 2 buckets. you need to consume before you add more data to it. If its a TCP socket based protocol (or any stream based), you need to just read the header, the header should have a indication of data size. malloc for that size, consume the data and then go read the next header.

Nish
  • 379
  • 2
  • 9
  • Actually reading the header is much better because I can just reserve memory one time and for the full packet. How can I read the size header? Thank you – Alberto Apr 04 '14 at 08:56
  • I just realized that the header give you the size of the fragmented message not the size of the full packet. So in that case this is useless – Alberto Apr 04 '14 at 09:12