문제

나는 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;
}
도움이 되었습니까?

해결책

이 문제를 해결하는 데 사용할 수있는 두 가지 트릭이 있습니다.

  1. Directive #Pragma Pack (1) 및 #Pragma Pack (POP) 예 : 사용 예 :

    #pragma pack(1)
    
    struct tight{           
       short element_1;       
       int *element_2;
    };
    #pragma pack(pop) 
    
  2. 편집 중에 두 개의 스트러크의 크기가 동일한 지 확인하려면이 트릭을 사용하십시오.

    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 바이트

자세한 내용을 찾으십시오 바운드 체크

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top