2012-03-30 11 views
37
#include "stdio.h" 
#include "string.h" 

main() 
{ 

    char string[] = "october"; // october is 7 letters 

    strcpy(string, "september"); // september is 9 letters 

    printf("the size of %s is %d and the length is %d\n\n", string, sizeof(string), strlen(string)); 

    return 0; 
} 

Salida:Sizeof vs STRLEN

el tamaño de septiembre es 8 y la longitud es de 9

¿Hay algo malo con mi sintaxis o qué?

+10

Estás escribiendo más allá del final de la matriz 'string'. Este es un comportamiento indefinido. 'string' solo puede contener 8 caracteres (7 para" octubre "y 1 para el terminador nulo). Cuando llama a 'strcpy', le está escribiendo 10 caracteres (9 para" septiembre "y 1 para el terminador nulo), lo que significa que ha pasado el final de la matriz y está sobrescribiendo la memoria adyacente. – Marlon

+11

Tenga en cuenta que 'sizeof' se calcula en * compile * time donde' strlen' es el tiempo de ejecución. – Naveen

+5

@Naveen: Tenga en cuenta que eso no es necesariamente cierto cuando se trata de VLA. – caf

Respuesta

1

Su matriz de destino tiene 8 bytes (longitud de "octubre" más \ 0) y desea poner 9 caracteres en esa matriz.

man strcpy dice: Si la cadena de destino de strcpy() no es lo suficientemente grande, entonces puede pasar cualquier cosa.

Por favor, dime lo que realmente quiere hacer, porque esto huele mal camino largo

+0

Este es el programa de prueba para comprender el funcionamiento de sizeof() – beparas

33

sizeof y strlen() hacer cosas diferentes. En este caso, su declaración

char string[] = "october"; 

es lo mismo que

char string[8] = "october"; 

lo que el compilador puede decir que el tamaño de string es 8. Esto lo hace en tiempo de compilación.

Sin embargo, strlen() cuenta el número de caracteres en la cadena en tiempo de ejecución. Entonces, después de llamar al strcpy(), string ahora contiene "septiembre". strlen() cuenta los caracteres y encuentra 9 de ellos. Tenga en cuenta que no ha asignado suficiente espacio para string para mantener "septiembre". Este es un comportamiento indefinido.

3

La salida es correcta porque

primer tamaño de serie de la sentencia fue asignado por el compilador que es 7 + 1 (octubre es de 7 bytes & 1 byte para terminador nulo en tiempo de compilación)

Segunda afirmación: eres copiando septiembre (cadena de 9 bytes a 8 bytes);

allí para usted tiene el tamaño de septiembre como 8 bytes (todavía strlen() no va a funcionar para septiembre que no tiene carácter nulo)

+1

La cadena literal '" septiembre "' contiene implícitamente el carácter nulo, por lo que 'strlen()' funcionará, si el programa no se ha bloqueado ya (debido a escritura más allá del final de la matriz 'string') –

-1

Debe eliminar buffer overflow problema en este ejemplo. Una forma de hacer esto - es utilizar strncpy:

memset(string, 0, sizeof(string)); 
strncpy(string, "september", sizeof(string)-1); 
+1

No, no, no. 'strncpy()', a pesar de su nombre, es la herramienta incorrecta para hacer cualquier cosa con ** cadenas **. En el ejemplo anterior, la 'cadena' resultante no será * cadena * porque ninguno de sus 8 elementos contendrá un terminador cero. – pmg

+0

¿Por qué herramienta incorrecta? Solucioné el problema de terminación de cadena. –

+0

Es la herramienta incorrecta para cadenas precisamente porque no tiene en cuenta el terminador cero que existe en cada cadena por definición (el diseño 'strncpy()' lo hace útil solo para ... errr ... * sin terminación instrumentos de cuerda*). Asegúrese de tener espacio y use 'strcpy()' (o, si puede usar BSD-isms, use 'strlcpy()'). – pmg