2009-07-26 97 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'。