2009-07-26 16 views
6

Podczas odbierania danych przez gniazdo przy użyciu recv, zauważyłem, że z:char array vs. wskaźnik char

 
char buffer[4]; 
memset(buffer, 0, 4); 
recv(socket, buffer, 4, 0); 

otrzymam

mesgx

"mesg" jest tym, co wysłałem, z dołączonymi losowymi postaciami.

Jeśli używam

 
char * method = (char *) malloc(4); 
memset(buffer, 0, 4); 
recv(socket, buffer, 4, 0); 

zamian otrzymam

mesg

Więc nie ma random stuff dołączany do mojego łańcucha. Stwierdziłem, że jeśli użyję char [5], to działa tak samo, ale tak naprawdę nie rozumiem dlaczego. Czy malloc (4) naprawdę przydziela 5 bajtów, a piąty to NUL?

Odpowiedz

16

Wezwanie do malloc(4) tak naprawdę alokuje tylko cztery bajty. To był zbieg okoliczności, że bajt w pamięci stał się pamięcią NUL, która zakończyła twój ciąg dla ciebie.

W przypadku, gdy przydzielono char buffer[4] na stosie, następnym bajtem był 'x', po którym następował jakiś inny materiał, więc ciąg znaków był kontynuowany aż do znalezienia następnego bajtu NUL.

Funkcje gniazda dotyczą tylko bajtów i nie traktują bajtów jako ciągów z końcową NUL lub czymkolwiek dodatkowym. Dostajesz dokładnie to, o co prosisz.

6

Potrzebujesz 5 znaków, aby poprawnie zakończyć NULL. NULL kończąca się liczy się jako jedna, więc jeśli potrzebujemy N znaków, przydziel N + 1. I odwrotnie, przy przydzielaniu N masz dostępną N-1 dla twoich treści.

+0

Myślałem tak samo, ale dlaczego to działa z malloc? – fresskoma

2

Nie można otrzymać więcej niż 4 char s jak tylko poprosił recv o maksymalnie 4 bajty do umieszczenia w buforze. Powinieneś sprawdzić wartość zwracaną przez recv, aby sprawdzić, ile faktycznie zwrócono bajtów.

Podejrzewam, że problem polega na tym, że nie jesteś ostrożny, aby wyprowadzać tylko 4 char s z dowolnej rutyny generującej dane wyjściowe. Jednym ze sposobów wyświetlenia początkowej zawartości bufora o wartości niezerowej zakończonej jest to: char.

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

Kompletny recv wezwanie fragment może być:

#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

Podejrzewam, że różnica jest przypadkowa. Kiedy używasz bufora jako łańcucha znaków, na przykład w printf(), będzie on odczytywany poza jego limitem aż do znalezienia "\ 0".

Powinieneś użyć bufora [5] lub malloc (5) w obu przypadkach. Zestaw memset() nie powinien być konieczny, lepiej umieścić bufor [4] = '\ 0' po recv().