c arrays flexible-array-member

Declaración de matriz sin usar en una estructura



arrays flexible-array-member (2)

¿Por qué C permite esto?

typedef struct s { int arr[]; } s;

donde la matriz arr no tiene un tamaño especificado?


Probablemente esté buscando matrices flexibles en C99. Los miembros de matriz flexible son miembros de tamaño desconocido al final de una estructura / unión.

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

También puede ver la razón del hack de estructura en primer lugar.

No está claro si es legal o portátil, pero es bastante popular. Una implementación de la técnica podría verse más o menos así:

#include <stdlib.h> #include <string.h> struct name *makename(char *newname) { struct name *ret = malloc(sizeof(struct name)-1 + strlen(newname)+1); /* -1 for initial [1]; +1 for /0 */ if(ret != NULL) { ret->namelen = strlen(newname); strcpy(ret->namestr, newname); } return ret; }

Esta función asigna una instancia de la estructura de nombre con el tamaño ajustado para que el campo de nombre pueda contener el nombre solicitado (no solo un carácter, como sugeriría la declaración de estructura).

A pesar de su popularidad, la técnica también es algo notoria: Dennis Ritchie lo ha llamado "amistad sin garantías con la implementación C". Una interpretación oficial ha considerado que NO se ajusta estrictamente al Estándar C, aunque parece funcionar en todas las implementaciones conocidas. Los compiladores que controlan cuidadosamente los límites de la matriz pueden emitir advertencias.


Esta es la característica C99 llamada arreglos flexibles , la característica principal es permitir el uso de características de matriz de longitud variable dentro de una estructura y R .. en esta respuesta a otra pregunta sobre miembros de matriz flexibles proporciona una lista de beneficios para usar matrices flexibles sobre punteros . El borrador del estándar C99 en la sección 6.7.2.1 Estructura y especificadores de unión párrafo 16 dice:

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

Por lo tanto, si tuviera una s* asignaría espacio para la matriz además del espacio requerido para la estructura , generalmente tendría otros miembros en la estructura:

s *s1 = malloc( sizeof(struct s) + n*sizeof(int) ) ;

el proyecto de norma en realidad tiene un ejemplo instructivo en el párrafo 17 :

EXAMPLE After the declaration: struct s { int n; double d[]; }; the structure struct s has a flexible array member d. A typical way to use this is: int m = /* some value */; struct s *p = malloc(sizeof (struct s) + sizeof (double [m])); and assuming that the call to malloc succeeds, the object pointed to by p behaves, for most purposes, as if p had been declared as: struct { int n; double d[m]; } *p; (there are circumstances in which this equivalence is broken; in particular, the offsets of member d might not be the same).