본문 바로가기
Language/C언어

C014_구조체 정렬하기

by OdOp 관리자 2023. 9. 16.
SMALL

C언어에서 구조체를 정렬할 때 멤버 중에서 가장 큰 자료형 크기의 배수로 정렬하게 됩니다. 

예를 들어 Person이라는 구조체가 아래와 같이 구성되었다고 가정해 봅시다. 

struct Person
{
    int age;
    char flag;
};

위와 같이 구성이 되면 이 구조체의 전체 크기는 8바이트가 됩니다. 

가장 큰 int자료형을 기준으로 세는 것이지요.

이렇게 되면 3바이트를 낭비하게 됩니다. 

낭비가 생기는 것을 알면서도 컴파일러가 이렇게 처리하는 이유는 CPU가 접근하기 쉬운 위치에 변수들을 배치하기 때문에 4바이트 또는 8바이트 단위로 끊는 바이트 패딩 작업을 수행하는 것입니다. 이때 중간중간 빈 공간이 생깁니다. 

다른 컴퓨터(시스템)에서 진행을 하게 되면 끊는 바이트 단위가 바뀔 수도 있습니다. 그래서 네트워크 통신을 할 때는 패킷의 사이즈를 정확하게 지정해야 합니다.

이를 해결하기 위해서 #pragma pack을 사용해야 합니다. 

 

#pragma pack

#pragma pack(push, 1)
struct Person
{
    int age;
    char flag;
};
#pragma pack(pop)

'#pragma pack(push, 1)'로 1바이트 단위로 끊는 바이트 패딩 적업을 수행할 수 있게 됩니다. 

다 사용했으면 '#pragma pack(pop)'으로 정렬 설정을 이전 상태(기본값)로 되돌려야 합니다. 

 

예제

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  


#pragma pack(push, 1)  //1바이트 크기로 정렬 
struct PacketHeader {
    char flags;
    int seq;
};
#pragma pack(pop)  
//정렬 설정을 이전 상태(기본값)로 되돌림

struct PacketHeader2 {
    char flags;
    int seq;
};

int main()
{
    struct PacketHeader header;
    struct PacketHeader2 header2;

    //PackHeader
    printf("%d\n", sizeof(header.flags));  //char은 1바이트
    printf("%d\n", sizeof(header.seq));  //int는 4바이트
    printf("%d\n", sizeof(header));  //구조체 전체 크기는 5바이트
    printf("%d\n", sizeof(struct PacketHeader));  //구조체 이름으로 구조체 전체 크기를 구해 5바이트
    //PackHeader2
    printf("%d\n", sizeof(header2.flags));  //char은 1바이트
    printf("%d\n", sizeof(header2.seq));  //int는 4바이트
    printf("%d\n", sizeof(header2));  //구조체 전체 크기는 8바이트
    printf("%d\n", sizeof(struct PacketHeader2));  //구조체 이름으로 구조체 전체 크기를 구해 8바이트
    return 0;
}

PacketHeader은 'pragma pack'을 사용하여 패딩 작업을 조절한 것이고 PacketHeader2는 그렇지 않은 것입니다. 

직접 작성해 보시면서 비교해 보면 좋을 것 같습니다. 

LIST

'Language > C언어' 카테고리의 다른 글

C016_함수, 매개변수 사용  (0) 2023.09.18
C015_함수에 대해  (3) 2023.09.17
C013_구조체 포인터 사용하기  (0) 2023.09.15
C012_struct, 구조체에 대해  (0) 2023.09.14
C011_배열 사용하기  (0) 2023.09.13