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;
}
¿Fue útil?

Solución

Hay dos trucos que pueden usarse para superar este problema

  1. 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) 
    
  2. 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 por

     printf("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 de long y unsigned char[2] en lugar de short, 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top