当使用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);
相反,我收到了
mesg
所以我的字符串中没有附加的随机内容 . 我想出如果我使用char [5]而不是它也可以,但我真的不明白为什么 . malloc(4)真的分配了5个字节,第五个是NUL吗?
4 回答
对
malloc(4)
的调用实际上只分配了四个字节 . 只是巧合,内存中的下一个字节恰好是NUL,它终止了你的字符串 .在你在堆栈上分配
char buffer[4]
的情况下,下一个字节碰巧是'x'
,后跟其他一些东西,所以你的字符串一直持续到找到下一个NUL字节 .套接字函数仅处理字节,并且不将字节视为具有尾随NUL的字符串或任何额外的字符串 . 你得到了你所要求的 .
您需要5个字符才能正确地终止NULL . 终止NULL计为1,因此如果我们需要N个字符,则分配N 1.或者相反,对于N的分配,您的N-1可用于您的内容 .
我怀疑差异是巧合 . 当您将缓冲区用作字符串时,例如在printf()中,它将被读取超过它的限制,直到找到'\ 0' .
在这两种情况下都应该使用buffer [5]或malloc(5) . memset()不一定是必需的,最好在recv()之后放一个缓冲区[4] ='\ 0' .
您不可能收到超过4个
char
,因为您只需要recv
,最多可将4个字节放入缓冲区 . 您应该检查recv
的返回值以查看实际返回的字节数 .我怀疑问题是你不小心只从生成输出的任何例程中输出4
char
. 显示可能非空终止的char
缓冲区的初始内容的一种方法是这样 .完整的
recv
调用代码段可能是: