Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C send method free buffer?

Tags:

c

free

send

I have a question about the send method of C.

int send (int socket, void *buffer, size_t size, int flags);

My code:

char *buffer = (char *)malloc(100*sizeof(char));
send(s, buffer, 100*sizeof(char), MSG_NOSIGNAL);

Now I was wondering if I should free the buffer myself or does the send method free it?

My code where I free the buffer:

char *buffer = (char *)malloc(100*sizeof(char));
send(s, buffer, 100*sizeof(char), MSG_NOSIGNAL);
free(buffer);

When I saw the error I thought I freed the buffer to soon and the send method was still using the memory.

Let me know.

like image 798
Tim Avatar asked Apr 09 '11 13:04

Tim


2 Answers

send does not free the buffer. You need to free it. Aside from the fact that it simply wasn't designed that way (socket functions are independent of heap functions), send would not actually "know" if the memory should be freed since it could be a pointer to the middle of an allocated chunk of memory or it could be a pointer to stack data.

It should be "safe" to immediately free the buffer after the send call because the function will have copied the data to its own internal buffers. The code you show would not cause a corruption problem (although I suspect there is more code involved since the buffer is not initialized as shown). It is possible for the heap to be corrupted earlier in the process and not cause an exception until later (e.g., the free after the send).

The return value of send indicates the number of bytes successfully sent (although not necessarily successfully delivered). So while it would be "safe" to free it, you would lose the unsent data if it wasn't all sent. If the entire buffer was not sent, you would need to call send again with the remaining amount.

like image 95
Mark Wilkins Avatar answered Sep 29 '22 20:09

Mark Wilkins


You can free the buffer after the send call returns, noting the following:

  • The entire buffer may not have been sent.
  • The call returns the number of bytes the kernel has copied into its own buffers. The rest you should keep.

This code may help you understand what is going on, but by no means should you base your own on this:

char *buf; // sizeof(*buf) must be 1 for pointer arithmetic
ssize_t sent = send(fd, buf, len, 0);
if (sent != -1) { // no error
    // move the unsent bytes to the start of the buffer
    memmove(buf, buf + sent, len - sent);
    // resize the buffer to fit the left over bytes
    buf = realloc(buf, len - sent);
}
like image 41
Matt Joiner Avatar answered Sep 29 '22 18:09

Matt Joiner