메모리 패킹
1.요약
#pragma pack을 이용하여 메모리를 특정 align으로 packing할 수 있다.
2.본문
데브피아에 다음과 같은 팁이 올라왔다.
-----------------------------------------------------------------
구조체 / 공용체 도는 클래스를 바이트 스트림으로 변화시켜야한다면 메모리를 패킹하자.
- 사용하는 구조체 또는 공용체 / 클래스를 바이트 스트림으로 변화시켜야한다면, 메모리를 1 바이트 정열을 시켜야 정확한 바이트 단위 크기를 갔습니다. 주로 통신 프로그램을 만드는 경우에 해당하겠군요
예 )
-----------------------------------------------------------------
그럼 왜 이런 방법을 사용해야하는지와 좀더 구체적인 용법을 알아보겠다.
먼저 alignment는 compiler에서 구조체/공용체 데이터를 처리하는 단위가 된다. 이것은 VC의 [Project Settings]의 C/C++탭의 Code Generation항목에서 조절 가능하다. 또한 컴파일러 옵션의 /Zp가 이러한 역활을 한다.
디폴트값은 8이다. 이것은 우리가 구조체를 만들면 8byte단위로 alignment가 정해진다는 의미이다.
다음과 같은 구조체가 있다.
typedef struct GTcpPacket위 구조체의 크기를 계산해보면
{
char mark1[8];
int len;
}GTCPPACKET, FAR * LPGTCPPACKET, *PGTCPPACKET;
GTcpPacket packet;size:12, 8
int nAllSize = sizeof(packet);
int nSize1 = sizeof(packet.mark1);
TRACE("size:%d, %d\n", nAllSize, nSize1);
구조체 전체의 크기가 12(8+4)이고 mark1의 크기가 8임을 알 수 있다.
typedef struct GTcpPacket와 같이 mark1의 크기를 1byte 늘렸다.
{
char mark1[9];
int len;
}GTCPPACKET, FAR * LPGTCPPACKET, *PGTCPPACKET;
결과를 출력해보면
size:16, 9
와 같이 된다. 이론적으로는 9+4 = 13되어야하겠지만 compiler의 alignmemnt의 영향으로 이러한 현상이 일어나는 것이다.
데이피아에 언급된 방법으로 alignment를 조절해보자.
#pragma pack(push,enter_byte_packing)size:13, 9
#pragma pack(1)
typedef struct GTcpPacket
{
char mark1[9];
int len;
}GTCPPACKET, FAR * LPGTCPPACKET, *PGTCPPACKET;
#pragma pack(push,enter_byte_packing)
이경우는 결과가 정상적으로 나왔다.
#pragma pack을 쓰지않고도 VC의 프로젝트 세팅에서 이러한 alignment를 조절할 수 있다고 앞서 설명했다. 그러나 이러한 방법은 프로젝트 전체에 걸처서 적용되기때문에 특정 구문/파일에만 적용할때는 데브피아에서 언급한 #pragma pack을 사용한다.
그런 #pragma pack의 용법을 좀더 구체적으로 알아보자.
프로토타입
#pragma pack( [ [ { push | pop}, ] [ identifier, ] ] [ n ] )push, pop이 있는것이 특이할 것이다. 이것은 컴파이러 스텍을 이용함을 의미한다. 즉 뒤에 붙는 identifier 로 push한 이후의 컴파일러 옵션은 n으로 지정한 값을 적용받고 pop하면 지정된 옵션이 풀리게된다.
MSDN의 예제에 보면 이러한 방법으로 헤더파일 전체를 특정 alignment로 지정하는것을 볼 수 있는데 다음과 같다.
#pragma pack( push, before_include1 )여기서 identifier는 그냥 구분자이므로 push때와 pop때에 일치되는것만 쓰면 어떤것이든 상관없다. 단... 중복해서 사용하지는 말기를...
#include "include1.h"
#pragma pack( pop, before_include1 )
출처 : http://blog.daum.net/sandwind/13423451