2012-03-21 7 views
8

que tienen código siguiente:¿Por qué el tamaño de un registro no es igual a la suma de los tamaños de sus campos?

type TRecord1 = record 
    myarr: array [0..31] of single: 
end; 
type TRecord2 = record 
    b1, b2, b3, b4, b5, b6: byte; 
end; 
type TRecord3 = record 
    myarr: array [0..31] of single:  
    b1, b2, b3, b4, b5, b6: byte; 
end; 

procedure TForm1.FormCreate(Sender: Tobject); 
begin 
    ShowMessage(IntToStr(SizeOf(TRecord1))+'+'+IntToStr(SizeOf(TRecord2))+ 
     '='+IntToStr(SizeOf(TRecord3))); 
end; 

El programa muestra el siguiente mensaje:

128+6=136 

¿Por qué es SizeOf(TRecord3) igual a 136 en lugar de 134?

+0

regla de oro: si está planeando usar algunas estructuras con archivos, declare que están '' empaquetadas ''. – OnTheFly

+2

Mi regla empírica sería nunca escribir representaciones binarias de registros en el archivo –

+0

Sí, evite almacenar datos binarios, pero la directiva empaquetada tiene su uso cuando se pasan registros durante E/S (dll, comunicación en serie, etc.). Sin embargo, se deben aplicar técnicas de conversión binarias/cadenas estandarizadas para nuevos desarrollos. –

Respuesta

15

Esto se debe al relleno añadido debido a la alineación de registros. TRecord3 tiene alineación de 4 ya que contiene single valores. Y así, el relleno se agrega al final del registro para que el tamaño sea un múltiplo exacto de 4. Es por eso que el tamaño es 136 en lugar del valor de 134 que estaba esperando.

Puede declarar que su registro es packed, o, de manera equivalente, establecer la opción del compilador de alineación en $ALIGN 1. Con una alineación de 1, no se agregará relleno al registro y SizeOf(TRecord3)=134. Sin embargo, recomiendo encarecidamente que no hagas esto. El uso de la alineación natural da como resultado el acceso a la memoria más eficiente para los registros. Por ejemplo, es más costoso para el procesador cargar un valor desalineado que cargar un valor alineado. Para un single o un integer, la alineación natural está en un bounday de 4 bytes. Para un double, la alineación natural se encuentra en un límite de 8 bytes, y así sucesivamente. Debe usar registros empaquetados si necesita compatibilidad binaria con otra biblioteca que usa registros empaquetados.

+2

Además, puede cambiar la declaración a 'escriba TRecord3 = registro empaquetado ...' para evitar la alineación de registros, aunque generalmente no es necesario. Los registros alineados funcionan mejor, pero en algunos casos es posible que necesite registros empaquetados. – GolezTrol

4

Esto se debe a la alineación. Los campos en el registro están alineados en 4 bytes u 8 bytes (o bytes cuando solo se usan bytes en el registro) de tal manera que el registro en una matriz todos los campos se seguirán alineando. Si desea que la fórmula funcione, debe usar un "registro empaquetado". Tenga en cuenta que los campos pueden estar desalineados y pueden obstaculizar el rendimiento.

Cuestiones relacionadas