2011-07-18 17 views
6

Tengo el siguiente tipo de código:¿Un miembro de matriz flexible aumenta el tamaño de una estructura?

typedef struct 
{  
    u32 count; 
    u16 list[]; 
} message_t; 
... 

message_t* msg = (message_t*)buffer; 
msg->count = 2; 
msg->list[0] = 123; 
msg->list[1] = 456; 

size_t total_size = sizeof(*msg) + sizeof(msg->list[0]) * msg->count; 

send_msg(msg, total_size); 

línea Problemático es la línea con sizeofs. No estoy seguro de que sea la forma correcta de contar el espacio necesario. ¿Contiene sizeof(*msg) algo sobre el miembro list?

Puedo probarlo con mi compilador, pero ¿todos los compiladores funcionan de manera similar en este caso?

+1

depende de la alineación –

+0

@Mitch Wheat: sí, tienes razón. Tu comentario es la respuesta correcta a la pregunta del título. +1 para ti. – SKi

Respuesta

9

Esto es lo que la norma dice:

Como caso especial, el último elemento de una estructura con más de un miembro de nombre puede tener un tipo de matriz incompleta; esto se llama un 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 el miembro de matriz flexible se hubiera omitido, excepto que puede tener más relleno de cola que la omisión implicaría.

+0

oh wow me olvidé de eso ... arreglando mi respuesta ... – ShinTakezou

+0

pero, ayúdenos a interpretarlo: ¿significa tamaño de estructura + tamaño de lista * número de elemento dará el tamaño correcto del "objeto", la forma en que el OP lo calcula, o de esta manera uno podría perder el relleno "extraño"? – ShinTakezou

+0

Gracias. La cita al estándar responde a mis preguntas. Aceptaré esta respuesta. Acerca del relleno: Causa "* excepto que puede tener más relleno posterior de lo que implicaría la omisión *" significa que el tamaño de (struct) puede ser diferente sin el miembro flexible de la matriz. Pero, en mi caso, no es un problema. – SKi

1

Su ejemplo funciona, ya que C no tiene matrices que aumentan dinámicamente cuando agrega elementos. Entonces, el tamaño de * msg es el tamaño de u32 + paddings, si lo hay, pero no contará para el miembro de la lista, que debe tener en cuenta cuando "asigna" el búfer y cuando quiere saber el tamaño real de ese " objeto ", como lo hiciste.

Cuestiones relacionadas