구조체의 크기
구조체의 크기는 구조체 변수 중 크기가 가장 큰 자료형을 기준으로 배수만큼 커진다. 즉 구조체의 크기는 변수의 크기에 패딩비트(구조체 크기를 가장 큰 자료형 기준으로 배수만큼 만들어주기 위해 추가되는 비트)가 더해져서 변수보다 더 큰 구조체 크기를 가질 수 있고 이는 메모리 낭비를 초래한다. 더 자세한 내용은 아래 링크를 참고한다.
이렇게 구조체의 사이즈가 커지는 원흉인 패딩비트는 pragma pack으로 제거할 수 있다. 그러나 32/64비트 운영체제에선 4바이트 기준으로 데이터를 처리하는 것이 가장 빠른 속도를 가지기 때문에 pragma pack의 사용은 속도 저하의 원인이 될 수 있다.
#pragma pack
pragma는 전처리구문 중 하나로 컴파일러에게 명령을 전달한다. 컴파일러에 종속적이라서 컴파일러 따라 실행되는 명령어가 다르지만, 많이 쓰이는 gcc, microsoft는 pragma pack을 사용할 수 있다.
pragma(n)
pragma(n) 명령어는 코드 내 모든 구조체의 기준 바이트를 n으로 만든다. 때문에 만약 n을 1로 두게 되면 패딩비트가 사라지게 된다.
아래 세 코드에서 pragma pack 사용으로 test1 구조체의 크기가 달라진 것을 확인할 수 있다.
#include <stdio.h> typedef struct test1 { char c; int i; }test1; int main() { test1 t1; printf("struct size : %d\r\n", sizeof(t1)); // struct size : 8 }
#include <stdio.h> #pragma pack(1) typedef struct test1 { char c; int i; }test1; int main() { test1 t1; printf("struct size : %d\r\n", sizeof(t1)); // struct size : 5 }
#include <stdio.h> #pragma pack(2) typedef struct test1 { char c; int i; }test1; int main() { test1 t1; printf("struct size : %d\r\n", sizeof(t1)); // struct size : 6 }
pragma(push,n) / #pragma(pop)
pragma(push,n) 명령어는 pragma(pop) 명령어가 나오기 전까지 선언된 구조체의 기준 바이트를 n으로 만든다. 코드 내의 모든 구조체가 아닌 일부만 적용하고 싶을 때 사용한다.
아래 코드에서 pragma pack(push, 1) ~ pragma pack(pop) 사이에 있는 test2 구조체만 크기가 작아진것을 확인할 수 있다.
#include <stdio.h> typedef struct test1 { char c; int i; }test1; #pragma pack(push, 1) typedef struct test2 { char c; int i; }test2; #pragma pack(pop) typedef struct test3 { char c; int i; }test3; int main() { test1 t1; test2 t2; test3 t3; printf("struct size : %d\r\n", sizeof(t1)); // struct size : 8 printf("struct size : %d\r\n", sizeof(t2)); // struct size : 5 printf("struct size : %d\r\n", sizeof(t3)); // struct size : 8 }