Estructura de relleno en el C
-
06-07-2019 - |
Pregunta
Lo he leído acerca de la estructura de relleno en el C:http://bytes.com/topic/c/answers/543879-what-structure-padding y escribió este código después de que el artículo, lo que deberá imprimir tamaño de 'struct pad' como de 16 bytes y el tamaño de 'struct pad2' debe ser de 12.-como creo que.He compilado este código con gcc, con diferentes niveles de optimización, incluso la sizeof() operador me da tanto de ellos de 16 bytes.¿Por qué es?
Esta información es necesaria para mí, porque de PS3 máquinas, donde los límites de bytes y la explotación de la totalidad de transferencia de dma es importante:
#include <stdio.h>
#include <stdlib.h>
struct pad
{
char c1; // 1 byte
short s1; // 2 byte
short s2; // 2 byte
char c2; // 1 byte
long l1; // 4 byte
char c3; // 1 byte
};
struct pad2
{
long l1;
short s1;
short s2;
char c1;
char c2;
char c3;
};
int main(void)
{
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
return EXIT_SUCCESS;
}
Solución
Hay dos trucos que pueden usarse para superar este problema
-
Usando la directiva #pragma pack (1) y luego #pragma pack (pop) ejemplo:
#pragma pack(1) struct tight{ short element_1; int *element_2; }; #pragma pack(pop)
-
Para verificar si los tamaños de dos estructuras son iguales durante la compilación, use este truco
char voidstr[(sizeof(struct1)==sizeof(struct2)) - 1]; //it will return error at compile time if this fail
Otros consejos
Sus estructuras, cada uno con un long
, que su plataforma aparentemente requiere estar en una de cuatro bytes de la frontera.La estructura debe ser al menos tan alineados como su más alineados miembro, así que tiene que ser de 4 bytes alineados, y una estructura del tamaño tiene que ser un múltiplo de su alineación en caso de que entra en una matriz.
Relleno adicional se requiere para hacer la long
de nuevo, y así el menor múltiplo de 4 es 16.
Dos consejos:
Usted puede calcular el desplazamiento de un campo
l1
porprintf("Offset of field %s is %d\n", "l1", offsetof(struct pad, l1);
Para obtener el
offsetof
macro necesitará#include <stddef.h>
(gracias caf!).Si desea pack de datos tan densamente como sea posible, el uso de
unsigned char[4]
en lugar delong
yunsigned char[2]
en lugar deshort
, y hacer la media aritmética para convertir.
EDITAR::El sizeof(struct pad2)
es 12.Tu código tiene un error;estructura P2
se declara de tipo struct pad
.Intente esto:
#define xx(T) printf("sizeof(" #T ") == %d\n", sizeof(T))
xx(struct pad);
xx(struct pad2);
P. S.Yo sin duda debe dejar de intentar responder a las preguntas después de la medianoche.
En PS3, no lo adivines. Use __attribute__((aligned (16)))
o similar. No solo garantiza que el inicio de la estructura se alineará en un límite adecuado (si es global o estático), sino que también rellena la estructura a un múltiplo de su alineación especificada.
Su código no muestra lo que cree que es, porque P1 y P2 están definidos como instancias de estructura de estructura. struct pad2 nunca se usa.
Si cambio la definición de P2 para que sea struct pad2, gcc decidirá hacerlo tamaño 12.
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
P1 y P2 tienen el mismo tipo " struct pad " tal vez quieras usar " struct pad2 " para P2.
Todas las CPU esperan que los tipos de datos integrados como (int, float, char, double) se almacenen en la memoria en su límite natural, en la dirección de su longitud. Por lo tanto, el relleno de la estructura se realiza para un acceso más rápido a los datos desde la memoria . Por ejemplo, Si se declara int, debería ocurrir en la memoria en una dirección múltiplo de 4, como
el tamaño de int es de 4 bytes.
Del mismo modo para el doble, reside en la memoria en múltiplo de 8.
Si la memoria está correctamente alineada, la CPU puede funcionar más rápido y funcionar de manera eficiente.
Para los siguientes ejemplos, supongamos:
Sizeof (int) = 4 byte
Sizeof (float) = 4 byte
Sizeof (char) = 1 byte
Encuentre detalles en BoundsCheck