Los tipos de datos de estructura C pueden terminar con un miembro de matriz flexible [1] sin tamaño especificado:
struct vectord { short len ; // debe haber al menos otro miembro de datos double arr []; // el miembro de la matriz flexible debe ser el último // El compilador puede reservar espacio de relleno adicional aquí, como puede hacerlo entre miembros de la estructura };
Normalmente, estas estructuras sirven como encabezado en una asignación de memoria variable más grande :
struct vectord * vector = malloc (...); vector -> len = ...; for ( int i = 0 ; i < vector -> len ; i ++ ) vector -> arr [ i ] = ...; // usa de forma transparente el tipo correcto (doble)
El sizeof
operador en tal a struct
da el tamaño de la estructura como si el miembro de la matriz flexible estuviera vacío. Esto puede incluir relleno agregado para acomodar el miembro flexible; el compilador también tiene la libertad de reutilizar dicho relleno como parte de la matriz misma. [2]
Es común asignar bytes. sizeof(struct) + array_len*sizeof(array element)
Esto no es incorrecto, pero puede asignar algunos bytes más de los necesarios: el compilador puede estar reutilizando parte del relleno incluido en sizeof(struct)
. Si esto es un problema, hay macros disponibles [3] para calcular el tamaño mínimo y garantizar que el relleno del compilador no se interrumpa.
Como la matriz puede comenzar en el relleno antes del final de la estructura, siempre se debe acceder a su contenido mediante indexación ( arr[i]
) o offsetof
, no sizeof
.
Los miembros de matriz flexibles se estandarizaron oficialmente en C99 . [4] En la práctica, los compiladores (por ejemplo, GCC , [5] MSVC [6] ) los proporcionaron mucho antes de que se estandarizara C99.
Los miembros de matrices flexibles no son oficialmente parte de C++ , pero las extensiones del lenguaje [7] están ampliamente disponibles.
Una matriz de tamaño cero solo es legal cuando la matriz es el último campo de una estructura o unión y cuando las extensiones de Microsoft (/Ze) están habilitadas.