구조체를 어떻게 선언하느냐에 따라 일반적으로 용량차이가 발생하게 된다.
typedef struct tagBITMAPFILEHEADER
{
WORD bfType; //4바이트 할당
DWORD bfSize; //4바이트 할당
WORD bfReserved1; //2바이트 할당
WORD bfReserved2; //2바이트 할당
DWORD bfOffBits; //4바이트 할당
} BITMAPFILEHEADER;
위와같은 구조체는 실제크기는 14바이트이지만 컴파일러는 16바이트로 처리하게 된다. 그 원리는 첫번째 워드가 실제크기는 2바이트지만 효율면에서 4바이트로 처리하는것이 좋기 때문에 4바이트로 할당을 하게 된다. 그리고 3번째 4번째 WORD는 4바이트 상위워드와 하위워드에 넣어 할당을 하게 되므로 총 합이 16바이트가 되게 된다.
일반적으로 이러한 구조체를 사용하는데 크게 문제가 되지 않지만 간혹 문제가 발생 할 경우가 생기게 마련이다. 예를 들어 비트맵같은경우에는 fread로 위에 구조체 내용을 채우는것이 효율이 좋으므로 아래와 같이 사용을 하게 된다.
fread((BYTE*)bitmap_file_header,1,sizeof(BITMAPFILEHEADER),fp);
하지만 sizeof(BITMAPFILEHEADER) 가 16이 되기때문에 문제가 발생하게 된다.
이럴경우에
GCC일 경우에는 __attribute__((packed)) 를 아래와 같이 사용하고
typedef struct __attribute__((packed)) tagBITMAPFILEHEADER // tagBITMAPFILEHEADER 이게 앞에 오면 안된다.
{
WORD bfType; //4바이트 할당
DWORD bfSize; //4바이트 할당
WORD bfReserved1; //2바이트 할당
WORD bfReserved2; //2바이트 할당
DWORD bfOffBits; //4바이트 할당
} BITMAPFILEHEADER;
win32에서는 아래와 같이 사용하면 되겠다.
#pragma pack(1) // 정렬 할 크기를 괄호안에 넣는다.
위 2가지 경우를 대비한 헤더를 만들어보면 아래와 같이 하면 된다.
#ifndef __GNUC__
#pragma pack(1)
#define __attribute__(a)
#endif
참으로 알면 알수록 어려워지는 C언어... 하지만 재밌다.~~~
'프로그래밍' 카테고리의 다른 글
[프로그래밍] thread 종료되지 않는 문제 (0) | 2014.02.16 |
---|---|
[프로그래밍] 각종 난수 발생 함수 링크 (0) | 2014.02.16 |
[프로그래밍] rand 함수의 gcc에서와 vc 에서의 차이점 (0) | 2010.03.31 |