char 数组与 char 指针
使用 recv,我注意到,与:
char buffer[4]; memset(buffer, 0, 4); recv(socket, buffer, 4, 0);
我收到
mesgx��
“mesg”是我发送的内容,附加了一些随机字符。
如果我使用
char * method = (char *) malloc(4); memset(buffer, 0, 4); recv(socket, buffer, 4, 0);
,我会收到
消息
所以我的字符串中没有附加任何随机内容。 我发现如果我使用 char[5] 代替它也可以工作,但我不太明白为什么。 malloc(4) 真的分配了 5 个字节,第五个字节是 NUL 吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对
malloc(4)
的调用实际上只分配了四个字节。 内存中的下一个字节恰好是 NUL,这只是巧合,它为您终止了字符串。在您在堆栈上分配
char buffer[4]
的情况下,下一个字节恰好是'x'
后跟一些其他内容,因此您的字符串继续直到找到下一个 NUL 字节。套接字函数仅处理字节,并且不会将字节视为带有尾随 NUL 或任何额外内容的字符串。 您得到的正是您所要求的。
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.
您需要 5 个字符才能正确以 NULL 结尾。 终止 NULL 算作 1,因此如果我们需要 N 个字符,则分配 N+1。 或者相反,对于 N 的分配,您有 N-1 个可用于您的内容。
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.
我怀疑这种差异是巧合。 当您将缓冲区用作字符串时,例如在 printf() 中,它将读取超过其限制,直到找到“\0”。
在这两种情况下都应该使用 buffer[5] 或 malloc(5)。 memset() 不是必需的,最好在 recv() 之后放置一个 buffer[4] = '\0'。
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().
您不可能收到超过 4 个
char
,因为您只要求recv
最多将 4 个字节放入缓冲区。 您应该检查recv
的返回值以了解实际返回了多少字节。我怀疑问题在于您不小心只从生成输出的任何例程中输出 4 个字符。 显示可能非空终止的
char
缓冲区的初始内容的一种方法是这样。完整的
recv
调用片段可能是:You can't possibly have received more than 4
char
s as you only askedrecv
for a maximum of 4 bytes to be placed into your buffer. You should check the return value ofrecv
to see how many bytes were actually returned.I suspect that the issue is that you are not being careful to only output 4
char
s from whatever routine is generating the output. One way of displaying the initial contents of a possibly non-null terminatedchar
buffer is this.A complete
recv
call snippet might be: