멋진 삶을 꿈꾸며

1 Articles, Search Results for '메모리패킹

  1. 2007/05/03 메모리 패킹 by 소리나는연탄

메모리 패킹

2007/05/03 10:27 / Resource

메모리 패킹



 
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; 

int nAllSize = sizeof(packet); 

int nSize1 = sizeof(packet.mark1); 

TRACE("size:%d, %d\n", nAllSize, nSize1); 

size:12, 8

구조체 전체의 크기가 12(8+4)이고 mark1의 크기가 8임을 알 수 있다.

typedef struct GTcpPacket 

{ 

    char mark1[9]; 

    int len; 

}GTCPPACKET, FAR * LPGTCPPACKET, *PGTCPPACKET; 

와 같이 mark1의 크기를 1byte 늘렸다.

결과를 출력해보면

size:16, 9

와 같이 된다. 이론적으로는 9+4 = 13되어야하겠지만 compiler의 alignmemnt의 영향으로 이러한 현상이 일어나는 것이다.

데이피아에 언급된 방법으로 alignment를 조절해보자.

#pragma pack(push,enter_byte_packing) 

#pragma pack(1) 

typedef struct GTcpPacket 

{ 

    char mark1[9]; 

    int len; 

}GTCPPACKET, FAR * LPGTCPPACKET, *PGTCPPACKET; 

#pragma pack(push,enter_byte_packing) 
size:13, 9

이경우는 결과가 정상적으로 나왔다.

#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 ) 

#include "include1.h" 

#pragma pack( pop, before_include1 ) 

여기서 identifier는 그냥 구분자이므로 push때와 pop때에 일치되는것만 쓰면 어떤것이든 상관없다. 단... 중복해서 사용하지는 말기를...

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기
Posted by 소리나는연탄.

Leave your greetings here.