Asignación de estructura con miembro de matriz flexible

2 minutos de lectura

Este es el código C99:

typedef struct expr_t
{
    int n_children; 
    foo data; // Maybe whatever type with unknown alignment
    struct expr_t *children[];
} expr_t;

Ahora, ¿cómo asigno memoria?

expr_t *e = malloc (sizeof (expr_t) + n * sizeof (expr_t *));

o

expr_t *e = malloc (offsetof (expr_t, children) + n * sizeof (expr_t *));

?

Es sizeof incluso garantizado para trabajar en un tipo con miembro de matriz flexible (GCC lo acepta)?

  • Sí, está garantizado que funciona. C99 §6.7.2.1/16 dice “el tamaño de la estructura será igual al desplazamiento del último elemento de una estructura idéntica que reemplaza el miembro de matriz flexible con una matriz de longitud no especificada”. Entonces sizeof(expr_t) es igual al valor que offsetof(expr_t, children) si hubieras redefinido children ser una matriz de cualquier tamaño determinado.

    – Adam Rosenfield

    1 oct 2012 a las 21:03

Asignacion de estructura con miembro de matriz
lococasta

expr_t *e = malloc (sizeof (expr_t) + n * sizeof (expr_t *)); está bien definido en C99. De la especificación C99 6.7.2.1.16:

Como caso especial, el último elemento de una estructura con más de un miembro con nombre puede tener un tipo de matriz incompleta; esto se denomina miembro de matriz flexible. En la mayoría de las situaciones, se ignora el miembro de matriz flexible. En particular, el tamaño de la estructura es como si se hubiera omitido el miembro de matriz flexible, excepto que puede tener más relleno final de lo que implicaría la omisión.

1646975769 454 Asignacion de estructura con miembro de matriz
Blagovest Büyükliev

Si el compilador acepta la declaración de una estructura con un miembro de matriz flexible, el sizeof El operador para esa estructura debería generar el tamaño de la estructura como si el miembro de matriz flexible no existiera.

La asignación correcta de tal estructura sería:

expr_t *e = malloc (sizeof(expr_t) + n * sizeof(struct expr_t *));

Todavía puede hacer este truco incluso si el compilador no admite miembros de matriz flexibles. Simplemente declare que el miembro de la matriz de su estructura tiene un tamaño de 1y luego asignar n - 1 elementos en lugar de n.

  • Pequeña advertencia: el requisito de relleno/alineación para una estructura será dictado por el elemento más restrictivo; un elemento de matriz flexible cuyo tipo requiere una alineación más restrictiva que cualquier otra cosa en la estructura puede cambiar el relleno y la alineación de la estructura. Por ejemplo, en algunas máquinas una estructura que contiene un char y un float[] podría ser de 4 bytes y requerir una alineación de cuatro bytes, aunque sin el double[] solo sería un byte.

    – Super gato

    5 de diciembre de 2012 a las 16:48

¿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