2009-07-26 98 views
6

当通过使用recv套接字接收数据,我注意到,具有:char数组与字符指针

 
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?

回答

16

malloc(4)的调用实际上只分配了四个字节。这只是巧合,内存中的下一个字节碰巧是一个NUL,它终止了你的字符串。

如果你在堆栈上分配了char buffer[4],下一个字节碰巧是'x',后面跟着一些其他的东西,所以你的字符串一直持续到找到下一个NUL字节为止。

套接字函数只处理字节,并不将字节视为具有尾随NUL或任何其他内容的字符串。你得到你所要求的。

6

您需要5个字符才能正确结束NULL。终止NULL计为1,所以如果我们需要N个字符,请分配N + 1。或者相反,对于N的分配,您有N-1个可用于您的内容。

+0

我以为这么多,但为什么它与malloc一起工作呢? – fresskoma 2009-07-26 22:08:58

2

您不可能收到超过4个char s,因为您只询问recv最多4个字节放入缓冲区。您应该检查返回值recv以查看实际返回的字节数。

我怀疑,问题是你不小心,只输出4 char期从任何程序生成输出。显示可能非空终止的缓冲区的初始内容的一种方法是这样的。

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

完整recv通话片断可能是:

#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); 
3

我怀疑的差异是巧合。当您使用缓冲区作为一个字符串,例如printf()的,它会被读过去,它的极限,直到“\ 0”被发现。

在这两种情况下,您都应该使用buffer [5]或malloc(5)。 memset()不应该是必须的,最好在recv()之后放置一个缓冲区[4] ='\ 0'。