Creative Motive
구조체 Pack 처리 본문
from : http://blog.naver.com/kkan22/80056919675
#pragma pack(push, 1)
packing의 줄임말입니다.
보통 운영체제나 머쉰에 따라 기본적으로 데이터를 처리하는 것이 조금씩 다릅니다.
그중에서 struct 라고 하는 구조체가 대표적인 예입니다...
예를들어
struct _tagMyRecord
{
char a;
int b;
};
라는 구조체가 있다고 할때 OS는 4로 Packing되어 있다면
char a; // 4바이트
int b; // 4바이트
해서 8바이트가 됩니다...
Packing을 1로 해줄경우에는
char a; // 1바이트
int b; // 4바이트
해서 5바이트가 됩니다...
이기종간 통신이나 OS가 다른 PC간에 통신을 할때... 1로 Packing해주면 같은 바이트수로
전송이 가능하고 같은 헤더파일을 사용할 수 있습니다... 더군다나 용량계산이 쉽죠...
보다 자세히 설명한 자료가 있어 펌 합니다.
기본적인 윈도우 환경에서의 데이터 정렬(Data alignment)은 4byte를 기준으로 이루어지게 된다.
struct A
{
char a;
short b;
};
위와 같은 구조체가 있다. 윈도우에서는 어떻게 메모리를 잡을까 생각을 해보자.
윈도우는 4byte가 가장 작은 메모리 할당량이다. 그러므로 어떠한 변수 하나를 잡기 위해서 4byte를 기준으로 계산하게 된다.
short = 2byte, char = 1byte이므로 4byte를 할당 받아 short을 먼저 2byte 할당하고 남는 2byte에 char를 할당하게 된다.
즉, 3byte를 사용하기 위해서 4byte의 메모리를 사용하게 되는 것이다.
하지만, 한가지 고려해야하는 부분은 컴파일러에 있다. Visual Studio는 기본적으로 8byte를 사용한다.
위 구조체를 할당하기 위해서는 8byte가 필요하게 되는 것이다.
#pragma pack(push, 1)
구조체
#pragma pack(pop)
위와 같은 방식으로 선언을 해준다면, Data alignment가 변하게 되는 것이다.
위의 선언은 데이터 정렬 기준은 1byte로 한다는 것이다.
즉, struct A는 위의 환경에서는 3byte만이 필요하게 되는 것이다.
메모리가 필요할 경우 무조건 1byte씩을 할당을 하게 되므로 불필요한 공간이 없이 필요한 공간만을 할당하게 되는 것이다.
#pragma pakc(pop)을 하지 않을 경우는 #pragma pack(push, 1)로 선언된 이후의 부분은 전부 적용이 되는 것이다.
이것에 신경을 잘 쓰지 않으면 프로젝트가 엉망이 될 수 있다. 주의!!!!
예) 프로젝트 중간에 pack을 했다면 같은 값을 pack이 된 곳과 안된곳의 값이 다르게 표현이 되게 된다.
이유는 구조체 자체의 메모리 할당이 서로 다르기 때문에 생기게 되는 곳이다.
가장 유용하게 사용되는 부분은 네트워크 통신에 사용되는 packet을 정의할 때 가장 유용하게 사용된다.
network packet은 서버 클라이언트에서 같이 사용하기 때문에 문제가 되는 점은 발견되지 않으며, network packet의 사이즈를 적절하게 해주기 때문에 더욱 유용한 것이다.