2010-10-29 9 views
17
const char* a; 

¿cómo me aseguro de que la cadena 'a' es nulo terminado? cuando a = "abcd" y hago sizeof (a), obtengo 4. ¿Eso significa que no tiene terminación nula? si lo fuera, habría obtenido 5?sizeof para un nulo terminado const char *

Respuesta

5

Si le entregan una matriz de caracteres que puede contener o no datos terminados en nulo, realmente no hay una buena manera de verificarlo. Lo mejor que puede hacer es buscar un carácter nulo hasta una longitud determinada (¡no indefinidamente!). Pero 0 no es exactamente un byte inusual de datos para encontrar en un área de memoria no inicializada.

Esta es una de las muchas cosas sobre el estándar de cadena de C de C que a mucha gente no le gusta. Encontrar la longitud de una cadena que un cliente le entrega es una operación de búsqueda O (n) en el mejor de los casos, y una falla de segmentación en el peor.

Otro problema, por supuesto, es que las matrices y punteros son intercambiables.Eso significa que array_name + 2 es lo mismo que &(array_name[2]), y sizeof(a) es sizeof(char*), no la longitud de la matriz.

11

Obtiene 4 porque ese es el tamaño de un puntero en su sistema. Si desea obtener la longitud de una cadena terminada en nulo, desea la función strlen en la biblioteca estándar C.

+0

'strnlen' por seguridad. – nmichaels

+0

'strnlen' es específico de la plataforma, no en el estándar. – jer

+6

@Nathon: 'strnlen' en realidad no agrega seguridad, ¿o sí? Si su función requiere una cadena terminada en nulo y no obtiene una (o si se especifica que una función devuelve una cadena terminada en nulo y no devuelve una), su código ya está roto. –

28

sizeof(a) le da el tamaño del puntero, no de la matriz de caracteres a la que apunta el puntero. Es lo mismo que si hubiera dicho sizeof(char*).

Es necesario utilizar strlen() para calcular la longitud de una cadena terminada en cero (tenga en cuenta que la longitud volvió no incluyen el terminador nulo, por lo que es strlen("abcd") 4, no 5). O bien, puede inicializar una matriz con la cadena literal:

char a[] = "abcd"; 
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer 

La cadena literal "abcd" termine con un nulo; todos los literales de cadena terminan nulos.

+1

El OP ya estaba usando 'const', por lo que' const char a [] 'es probablemente una mejor idea que' char a [] '. – aschepler

+4

Para aclarar aún más, 'strlen()' solo proporcionará la leg lógica de datos en la matriz char, no la cantidad de bytes asignados para ella. No creo que haya una manera de obtener ese número. –

4

sizeof(a) es sizeof(const char*), el tamaño del puntero. No se ve afectado por el contenido de a. Para eso, quiere strlen.

Además, todos los literales de comillas dobles como su "abcd" en código fuente son terminados automáticamente.

1

sizeof (a) devuelve el tamaño de const char *a ... no el tamaño de lo que apunta. Puede usar strlen(a) para determinar la longitud de la cadena terminada en nulo y no, el resultado de strlen no incluye el terminador nulo.

6

El problema aquí es que está confundiendo sizeof() que es una operación en tiempo de compilación con la longitud de una cadena que es una operación en tiempo de ejecución. La razón por la que obtiene 4 de vuelta cuando ejecuta sizeof(a) es que a es un puntero y el tamaño típico de de un puntero en C es de 4 bytes. Para obtener la longitud de la cadena use strlen.

Para la segunda pregunta, cómo asegurarse de que una cadena tiene un final nulo. La única forma de hacer esto definitivamente es anulando la cadena por ti mismo. Dado solo un char*, no hay manera de garantizar al 100% que esté terminado de manera nula. Se debe tener mucho cuidado para asegurar que el contrato entre el productor y el consumidor del char* se entiende como quién termina la cadena.

+0

aah ... soy estúpido. Pero cuando hago strlen (a) obtengo 4, y sé que tiene "abcd" (de gdb). – hari

+0

@hari, 4 es correcto porque la longitud de la cadena "abcd" es de hecho 4. Sin embargo, los requisitos de memoria para 'a' son' strlen (a) + 1' para manejar el terminador nulo. Esta es una de las partes de C que solo te tomará un tiempo acostumbrarte. – JaredPar

+0

Eso es porque la longitud de "abcd" es 4. strlen no cuenta el terminador nulo. – jer