2009-07-26 24 views
6

Cuando se reciben datos a través de un conector usando recv, me he dado cuenta de que, con:matriz de caracteres vs puntero char

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

recibo

mesgx

"mesg" es lo que envié, con algunos caracteres aleatorios añadidos.

Si uso

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

lugar, recibo

mesg

Así que no hay cosas al azar añade a mis cadena. Descubrí que si uso char [5] también funciona, pero realmente no entiendo por qué. ¿Malloc (4) realmente asigna 5 bytes, el quinto es un NUL?

Respuesta

16

La llamada a malloc(4) realmente solo asigna cuatro bytes. Fue solo una coincidencia que el próximo byte en la memoria resultó ser un NUL, que terminó su cadena por usted.

En el caso donde asignó char buffer[4] en la pila, el siguiente byte resultó ser 'x' seguido de algunas otras cosas, por lo que su cadena simplemente continuó hasta que encontró el siguiente byte NUL.

Las funciones de socket solo se ocupan de los bytes, y no tratan los bytes como cadenas con un NUL final o algo extra. Obtienes exactamente lo que pides.

6

Necesita 5 caracteres para terminar correctamente NULL. El NULL de terminación cuenta como uno, de modo que si necesitamos N caracteres, asigne N + 1. O por el contrario, para una asignación de N, tiene N-1 disponible para su contenido.

+0

Lo pensé mucho, pero ¿por qué funciona con malloc? – fresskoma

2

No es posible que haya recibido más de 4 char s, ya que solo pidió recv para un máximo de 4 bytes para colocar en el búfer. Debería verificar el valor de retorno de recv para ver cuántos bytes se devolvieron realmente.

Sospecho que el problema es que no se está cuidando de generar solo 4 char s desde la rutina que esté generando la salida. Una forma de mostrar el contenido inicial de un búfer char posiblemente no terminado nulo es esto.

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

Un fragmento completo recv llamada podría ser:

#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

Sospecho que la diferencia es una coincidencia. Cuando utiliza el búfer como una cadena, por ejemplo, en printf(), se leerá más allá de su límite hasta que se encuentre un '\ 0'.

Debe usar el buffer [5] o malloc (5) en ambos casos. El memset() no debería ser necesario, mejor pon un buffer [4] = '\ 0' después del recv().

Cuestiones relacionadas