6

When receiving data through a socket using recv, I've noticed that, with:

char buffer[4];
memset(buffer, 0, 4);
recv(socket, buffer, 4, 0);

I receive

mesgx��

"mesg" being what I sent, with some random characters appended.

If I use

char * method = (char *) malloc(4);
memset(buffer, 0, 4);
recv(socket, buffer, 4, 0);

instead, I receive

mesg

So there's no random stuff appended to my string. I figured out that if I use char[5] instead it works as well, but I do not really understand why. Does malloc(4) really allocate 5 bytes, the fifth being a NUL?

4 Answers 4

16

The call to malloc(4) really only allocates four bytes. It was just coincidence that the next byte in memory happened to be a NUL, which terminated your string for you.

In the case where you allocated char buffer[4] on the stack, the next byte happened to be an 'x' followed by some other stuff, so your string just continued until it found the next NUL byte.

Socket functions deal with bytes only, and don't treat the bytes as strings with a trailing NUL or anything extra. You get exactly what you ask for.

Sign up to request clarification or add additional context in comments.

Comments

6

You need 5 characters to be properly NULL terminated. The terminating NULL counts as one, so if we need N characters, allocate N+1. Or conversely, for an allocation of N you have N-1 available for your content.

Comments

3

I suspect the difference is a coincidence. When you use buffer as a string, for example in printf(), it will be read past it's limit until a '\0' is found.

You should use buffer[5] or malloc(5) in both cases. The memset() shouldn't be necessary, better put a buffer[4] = '\0' after the recv().

Comments

2

You can't possibly have received more than 4 chars as you only asked recv for a maximum of 4 bytes to be placed into your buffer. You should check the return value of recv to see how many bytes were actually returned.

I suspect that the issue is that you are not being careful to only output 4 chars from whatever routine is generating the output. One way of displaying the initial contents of a possibly non-null terminated char buffer is this.

printf("%.4s\n", buffer);

A complete recv call snippet might be:

#define MAX_BUF_LEN (512)
char buffer[MAX_BUF_LEN];
ssize_t count = recv(socket, buffer, MAX_BUF_LEN, 0);

if (count > 0)
    printf("%.*s\n", count, buffer);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.