문제
나는 c에서 구조 패딩에 대해 이것을 읽었습니다.http://bytes.com/topic/c/answers/543879-what-structure-padding기사 다음 에이 코드를 썼습니다. 16 바이트와 같은 '구조물 패드'크기를 인쇄해야하며 'struct pad2'의 크기는 12입니다. 나는 다른 수준의 최적화로 GCC 로이 코드를 컴파일했으며, () 연산자조차도 둘 다 16 바이트를 제공합니다. 왜 그런가요?
이 정보는 PS3 머신 때문에 필요합니다. BYTE 경계와 전체 DMA 전송의 악용이 중요합니다.
#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;
}
해결책
이 문제를 해결하는 데 사용할 수있는 두 가지 트릭이 있습니다.
Directive #Pragma Pack (1) 및 #Pragma Pack (POP) 예 : 사용 예 :
#pragma pack(1) struct tight{ short element_1; int *element_2; }; #pragma pack(pop)
편집 중에 두 개의 스트러크의 크기가 동일한 지 확인하려면이 트릭을 사용하십시오.
char voidstr[(sizeof(struct1)==sizeof(struct2)) - 1]; //it will return error at compile time if this fail
다른 팁
귀하의 구조에는 각각 a가 포함됩니다 long
, 플랫폼은 분명히 4 바이트 경계에 있어야합니다. 구조는 최소한 정렬 된 부재만큼 정렬되어야하므로 4 바이트 정렬되어야하며 구조의 크기는 배열에 들어가는 경우 다중 정렬이어야합니다.
추가 패딩이 필요합니다 long
정렬되어 4 중 가장 작은 배수는 16입니다.
두 가지 조언 :
필드의 오프셋을 계산할 수 있습니다
l1
~에 의해printf("Offset of field %s is %d\n", "l1", offsetof(struct pad, l1);
얻기 위해
offsetof
매크로가 필요합니다#include <stddef.h>
(감사합니다 CAF!).가능한 한 밀도로 데이터를 포장하려면 사용하십시오.
unsigned char[4]
대신에long
그리고unsigned char[2]
대신에short
, 산술을 변환 할 수 있습니다.
편집하다:: sizeof(struct pad2)
~이다 12. 코드에는 버그가 있습니다. 구조 P2
유형으로 선언됩니다 struct pad
. 이 시도:
#define xx(T) printf("sizeof(" #T ") == %d\n", sizeof(T))
xx(struct pad);
xx(struct pad2);
추신 : 자정 이후에 질문에 대답하려고하지 말아야합니다.
PS3에서는 추측하지 마십시오. 사용 __attribute__((aligned (16)))
, 또는 유사한. 구조의 시작이 적절한 경계 (글로벌 또는 정적 인 경우)에 정렬 될 수있을뿐만 아니라 구조를 지정된 정렬의 배수로 채 웁니다.
P1과 P2가 모두 Struct Pad의 인스턴스로 정의되기 때문에 코드는 귀하의 생각을 표시하지 않습니다. Struct Pad2는 사용되지 않습니다.
P2의 정의를 변경하여 Struct Pad2가되면 GCC는 실제로 크기 12로 결정합니다.
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
P1과 P2는 동일한 유형의 "struct pad"를 가지고 있습니다. 아마도 p2에 "struct pad2"를 사용하려고합니다.
모든 CPU는 (int, float, char, double)과 같은 내장 데이터 유형이 자연 경계에서 메모리에 저장 될 것으로 예상합니다. 그래서 길이의 주소로 구조 패딩은 메모리에서 데이터에 더 빠르게 액세스하기 위해 수행됩니다. 예를 들어, int가 선언되면 4의 주소 다중 주소의 메모리에서 발생해야합니다.
int의 크기는 4 바이트입니다.
이와 마찬가지로 이중의 경우 8의 배수로 메모리에 있습니다.
메모리가 올바르게 정렬되면 CPU가 더 빠르게 실행되고 효율적으로 작동 할 수 있습니다.
다음 예제는 다음과 같이 가정 해 봅시다.
크기 (int) = 4 바이트
크기 (float) = 4 바이트
크기 (char) = 1 바이트
자세한 내용을 찾으십시오 바운드 체크