Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

char array vs. char pointer

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?

like image 999
fresskoma Avatar asked Jul 26 '09 22:07

fresskoma


3 Answers

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.

like image 83
Greg Hewgill Avatar answered Sep 30 '22 05:09

Greg Hewgill


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.

like image 20
Dirk Eddelbuettel Avatar answered Sep 30 '22 07:09

Dirk Eddelbuettel


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().

like image 37
Henk Holterman Avatar answered Sep 30 '22 07:09

Henk Holterman