estofamento estrutura em C
-
06-07-2019 - |
Pergunta
Eu li este sobre a estrutura estofamento em C: http://bytes.com/topic/c/answers/543879- what-estrutura de preenchimento e escreveu este código depois do artigo, o que deve imprimir o tamanho de 'almofada struct' como 16 bytes e o tamanho do 'pad2 struct' deve ser 12. -como eu acho. Eu compilei este código com gcc, com diferentes níveis de otimização, mesmo o operador sizeof () me dá ambos de 16 bytes. Por que é?
Esta informação é necessária para mim, porque de máquinas PS3, onde os limites de byte e exploração da transferência dma completo é 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;
}
Solução
Existem dois truques que podem ser usados ??para owercome este problema
-
Usando #pragma pack directiva (1) e, em seguida, #pragma Pack (POP) exemplo:
#pragma pack(1) struct tight{ short element_1; int *element_2; }; #pragma pack(pop)
-
Para verificar se os tamanhos de duas estruturas são as mesmas durante o uso compilação este truque
char voidstr[(sizeof(struct1)==sizeof(struct2)) - 1]; //it will return error at compile time if this fail
Outras dicas
As suas estruturas incluem, cada um long
, que sua plataforma aparentemente requer para ser em um limite de quatro bytes. A estrutura deve ser pelo menos tão alinhado como o seu membro mais alinhados, de modo que tem que ser 4 bytes alinhados, e um tamanho da estrutura tem de ser um múltiplo do seu alinhamento em caso ele entra em uma matriz.
estofamento extra é necessário para fazer a long
alinhados, e assim o menor múltiplo de 4 é de 16.
Dois conselhos:
-
Você pode calcular o deslocamento de um
l1
campo porprintf("Offset of field %s is %d\n", "l1", offsetof(struct pad, l1);
Para obter o macro
offsetof
você precisará#include <stddef.h>
(graças CAF!). -
Se você quer embalar dados tão densamente quanto possível, o uso
unsigned char[4]
vez delong
eunsigned char[2]
vez deshort
, e fazer a aritmética para converter.
Editar :: A sizeof(struct pad2)
é 12. Seu código tem um bug; estrutura P2
é declarado de tipo struct pad
. Tente isto:
#define xx(T) printf("sizeof(" #T ") == %d\n", sizeof(T))
xx(struct pad);
xx(struct pad2);
P.S. I definitivamente deve parar de tentar responder a perguntas Então, depois de meia-noite.
No PS3, não acho. Use __attribute__((aligned (16)))
, ou similar. Não só garantir que o início da estrutura será alinhado em um limite adequado (se global ou estática), também almofadas a estrutura para um múltiplo de seu alinhamento especificado.
Seu código não está mostrando o que você pensa que é, porque tanto P1 e P2 são definidos como casos de almofada struct. pad2 struct não é sempre utilizada.
Se eu mudar a definição de P2 para que seja pad2 struct, gcc, de fato, decidir torná-lo do tamanho 12.
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
P1 e P2 têm o mesmo tipo "struct pad" talvez você queira usar "pad2 struct" para P2.
Todos CPU esperar que o construído em tipos de dados como (int, float, char, double) são armazenados na memória em seu limite natural, no endereço de sua estrutura preenchimento length.So é feito para um acesso mais rápido de dados da memória . Por exemplo, Se int é declarado, que deveria ocorrer na memória num múltiplo endereço de 4, como
tamanho do int é de 4 bytes.
Da mesma forma para o dobro, ele reside na memória ao múltiplo de 8.
Se a memória está alinhada corretamente, CPU pode correr mais rápido e trabalhar de forma eficiente.
Para os exemplos seguintes, vamos supor:
sizeof (int) = 4 bytes
sizeof (flutuador) = 4 bytes
Sizeof (char) = 1 byte
Encontre detalhes sobre BoundsCheck