matriz de caracteres en estructuras: ¿por qué strlen () devuelve el valor correcto aquí?

4 minutos de lectura

matriz de caracteres en estructuras ¿por que strlen devuelve
máx.

Tengo un programa simple como este:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct 
{
    int numberOfDays;
    char name[10];
} Month;


int main(void) 
{
    const Month months[12] = { 
        { 31, {'J', 'a', 'n'} },
        { 28, {'F', 'e', 'b'} }
    };

    printf("%zu\n", strlen(months[0].name));
    printf("%zu\n", sizeof(months[0].name));

    printf("%zu\n", strlen(months[1].name));
    printf("%zu\n", sizeof(months[1].name));

    return 0;
}

La salida es así:

3
10
3
10

entiendo porque sizeof(months[i].name) imprime 10, pero ¿por qué strlen devolver el valor correcto en este caso?

Mi pensamiento fue que strlen cuenta hasta el primero '\0'pero el char name[3] la matriz no termina en nulo. Según tengo entendido, ¿debería ser un comportamiento indefinido? ¿Solo funciona por accidente?

Me pregunto cuál es el diseño de la memoria en lo anterior months[12] formación.

  • INCORRECTO. Esto no es la UB. El resto de la estructura se inicializa a ceros.

    – Jonathan Reinhart

    14 de abril de 2015 a las 11:46

  • Lo siento, son mis chicos malos. En la estructura en escribió char name[10] pero en la pregunta de la que hablé char name[3]. Sin embargo, ambos funcionan, eso es lo que me sorprende.

    – Máx.

    14 de abril de 2015 a las 11:49

  • @Max Por favor, no edite la pregunta de una manera que haga que las respuestas ya proporcionadas parezcan fuera de contexto. Gracias.

    – Sourav Ghosh

    14 de abril de 2015 a las 11:53


  • Tenía más sentido antes de editar – el sizeof resultados

    – Veleta

    14/04/2015 a las 11:55

matriz de caracteres en estructuras ¿por que strlen devuelve
Sourav Ghosh

TL; DR Respuesta: No, este es un comportamiento bien definido.

Explicación: según el C11 documento estándar, capítulo 6.7.9, inicialización,

Si hay menos inicializadores en una lista entre llaves que elementos o miembros de un agregado, o menos caracteres en una cadena literal utilizada para inicializar una matriz de tamaño conocido que elementos en la matriz, el resto del agregado debe inicializarse implícitamente igual que los objetos que tienen una duración de almacenamiento estática.

En tu caso, tienes un char gama de 10 elementos

 char name[10];

y ha proporcionado un inicializador para solo 3 elementos, como

{ 31, {'J', 'a', 'n'} },

Entonces, el resto de los elementos en name se inicializa a 0 o '\0'. Entonces, en este caso, strlen() devuelve el resultado correcto.

Nota: Por favor, no confíes en esto. método por nulidad de instrumentos de cuerda. En caso de que proporcione la cantidad exacta de elementos como inicializador, no habrá terminación nula.


EDITAR:

en caso de que el name la definición se cambia a char name[3] e inicializado con tres chars, entonces, según la nota anterior, el uso de strlen() (y familia) serán comportamiento indefinido ya que invadirá el área de memoria asignada en busca de terminar nulo.

  • en ese caso tu están suerte, ya que solo “sucede” que hay un 0 final.

    – Veleta

    14 de abril de 2015 a las 11:49

  • @WeatherVane no tiene suerte; es solo que algunos bytes de los pequeños enteros resultan ser 0, y también (creo) que la regla de inicialización de llaves de Sourav llenaría los 10 meses restantes en la matriz con 0. Así que strlen() funcionará pero devolverá longitudes inesperadas.

    – Peter – Reincorporar a Mónica

    14 de abril de 2015 a las 11:52

  • @PeterSchneider eso fue lo que quise decir con “suerte”. El 0 final no es parte de la matriz.[3]: no fue por diseño, fue por casualidad.

    – Veleta

    14 de abril de 2015 a las 11:53


  • @PeterSchneider OP cambió el código, si eso es lo que le preocupa.

    – Sourav Ghosh

    14 de abril de 2015 a las 11:54

  • @Max, en realidad no es tan vasto como crees. algo relacionado con Principio de Pareto. 😉

    – Sourav Ghosh

    14 de abril de 2015 a las 12:10


1647720427 222 matriz de caracteres en estructuras ¿por que strlen devuelve
gnasher729

La razón es que sus meses son, de hecho, nulos. Si tiene una matriz con 10 elementos y tiene un inicializador para 3 elementos, el resto se llena con 0. Si tuviera un mes con 11 caracteres, el compilador se lo diría. Si tuviera un mes con 10 caracteres, estaría en problemas porque no habría terminación nula y el compilador no se lo diría.

Cuando inicializa parcialmente el structaquellas partes no inicializadas específicamente se establecen en 0.

Entonces las cadenas tienen un 0 de terminación y así strlen() devuelve el valor correcto.

#include <stdio.h>
#include <string.h>

int main(){
int i;
    char s[10] = {'a', 'b', 'c'};
    for (i=0; i<10; i++)
        printf("%d ", s[i]);
    printf("\n%d\n", strlen(s));
    return 0;
}

Salida del programa:

97 98 99 0 0 0 0 0 0 0
3

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad