C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[553] 항목을 추가해도 구조체 크기를 일정하게 만드는 트릭.
김태선 [jsdkts] 6907 읽음    2005-12-22 17:21
어떤 바이너리 파일의 헤더를 구조체로 만들고 싶습니다.
그런데  어떤 이유때문에 꼭 256 바이트로 만들고 싶네요.
헤더의 항목은 작업하다 보면 여러개 추가될 것입니다.

이러면 보통 다음과 같이 합니다.
편의상 다음과 같은 의사 명령으로 1바이트 메모리 경계를 쓴다고 합시다.
디폴트로는 4바이트 메모리 경계인거는 다 아시죠.
#pragma pack(1)

typedef struct tagTHead
{
    char    IntroMsg[41];
    int    Count;
    char    Reserved[256 - 45]; 
} THead;
처음에는 레코드 갯수만 저장하는 Count 변수와 파일의 신원을 나타내는 정보 메시지가 들어가는 두개의 항목으로만
구성합니다. 하지만 나중에 항목을 수십개로 늘일 것입니다.

256 바이트에 꼭 맞추려면 위 두 항목의 사이즈를 256 바이트에서 빼서 계산해야 겠죠.
보통 이렇게 합니다.
그런데 빈번히 항목이 늘어나면 이거 계산하는거 귀잖습니다.
항목이 10개 이상만 넘어가도 그거 계산하려면 .... 계산기 꺼내야 함다.
혹 잘못 계산이라도 하면... 도움이 안되는 친구인 제길슨을 찾게 되죠.

이 계산을 컴파일러에게 맡기는 방법은 없을까요?

다음과 같은 offsetof 를 응용한 트릭으로 이를 해결할 수 있습니다.

#pragma pack(1)

typedef struct tagTHead
{
    char    IntroMsg[41];             
    int    Count;

    char    reserved;
    char    Reserved[256 - offsetof(tagTHead, reserved) - 1];
} THead;

#pragma pack()

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Caption = sizeof(THead);
}
//---------------------------------------------------------------------------

빈 영역을 위한 Reserved 영역을 가르키는 항목이 이렇게 변했죠.
char    Reserved[256 - offsetof(tagTHead, reserved) - 1];

생각같아서는
char    Reserved[256 - offsetof(tagTHead, Reserved)];
로 하고 싶은데 이는 문법에서  허용하지 않습니다.
Reserved 가 아직 생성되지 않은 시점이라는 이유 때문입니다.
그래서 임시 변수 reserved 를 위에 적어주고 이 변수의 크기인 1을 빼주는 방법을 쓰면 됩니다.

그러면 이제 항목이 아무리 많이 늘어나도 항상 헤더 구조체의 크기는 256바이트를 일정하게 유지하게 됩니다.

예제는 1바이트 메모리 경계 상태를 대상으로 한 것인데
디폴트인 4바이트 경계를 가지는 경우는
char reserved;
가 4바이트 메모리를 차지하므로
char    Reserved[256 - offsetof(tagTHead, reserved) - 4];
를 해줘야 한다는 것만 기억하면 됩니다.

확인해 보면 원하는 사이즈가 화면에 찍힙니다. ^^;



깜빡했었는데
이건 union을 써서 더 쉽게 해결하는 방법이 있고 이게 경우에 따라서는 좀 더 바람직합니다.

typedef union
{
   struct  
   {
    char    IntroMsg[41];             
    int    Count;
   };
   char    Reserved[256]; 
} THead;
김태선 [jsdkts]   2006-03-07 10:40 X
union을 사용하는 경우,
멤버로 클래스가 된다면

    char    reserved;
    char    Reserved[256 - offsetof(tagTHead, reserved) - 1];

와 같은 방식이
정말 유용하게 사용될 수 있습니다.
키예프 [sakim]   2006-03-28 15:06 X
아.. 바로 제가 찾고있던 내용입니다, 유용한정보 정말 고맙습니다

+ -

관련 글 리스트
553 항목을 추가해도 구조체 크기를 일정하게 만드는 트릭. 김태선 6907 2005/12/22
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.