메뉴 건너뛰기


Developer > Application
구조체를 선언하고 이를 객체화 했을 경우 메모리가 잡히게 됩니다.
이때 각 구조체 변수에 지정할 수 있는 값의 범위를 계산 할 수 있다면 Bit Field를 사용하여 구조체가 메모리에 잡히는 크기를 줄일 수 있습니다.
 
예를 들어 참, 거짓을 담을 플래그 변수를 정의하기 위해 1byte의 char형을 선언하는 것이 보통인데...
사실 1혹은 0을 지정하기 위해서는 1bit만 있으면 충분합니다.
 
또한 0~1000까지 저장해야 하는 변수가 필요하다면 unsigned short형 변수를 지정하면 되겠지만 사실 10bit면 1024개의 값을 저장할 수 있기 때문에 6bit의 낭비가 일어납니다.
 
더 크게 생각해 보면 0~100000까지를 저장하기 위해서는 17bit면 되지만 이를 저장할 수 있는 변수는 unsigned int 혹은 long형으로 4바이트가 되어 15bit의 낭비가 일어납니다.
 
어찌되었건... 이런식으로 구조체에 선언된 각 필드가 메모리 낭비가 심할때는 사용할 Bit를 지정함으로서 그 크기를 줄일 수 있습니다.
 
Bit Field를 지정하는 방법은 일반적인 선어 뒤에 콜론을 붙이고 사용할 Bit수를 지정하면 됩니다.
다음의 예를 참조하세요. 
#include <stdio.h> struct bitfields{ unsigned long num:17; // 0~131071 unsigned short count:10; // 0~1023 unsigned char flag:1; // 0~1 }; struct nobitfields{ unsigned long num; // 0~4294967295 unsigned short count; // 0~65536 unsigned char flag; // 0~255 }; int main(int argc, char *argv[]) { struct bitfields bf; struct nobitfields nf; printf("nobitfields size: %d\n", sizeof(nf)); printf("bitfields size: %d\n", sizeof(bf)); bf.num=100000; bf.count=1000; bf.flag=1; printf("bf.num=%d\n", bf.num); printf("bf.count=%d\n", bf.count); printf("bf.flag=%d\n", bf.flag); return 0; }
 
 
위의 실행결과는 다음과 같습니다.
 
nobitfields size: 16
bitfields size: 8
bf.num=100000
bf.count=1000
bf.flag=1
 
즉 전체 크기가 16byte가 소요될 구조체가 Bit Field를 사용함으로 8Byte로 구현이 가능했습니다.
근데 생각해 보면 nobitfields 구조체의 경우 각 필드의 크기를 모두 더하면 7Byte일텐데... 8Byte가 나오는 걸 알 수 있습니다. 또 bitfields 구조체의 경우도 각 Field의 Bit수를 더하면 28bit인데 8Byte 즉 64bit나 잡힌걸 알 수 있습니다.
 
이것은 컴퓨터의 Bit Alignment와 Padding 현상에 의해서 생긴 문제로서 CPU는 처리를 쉽게 하기 위해 자신의 Word크기로 메모리를 잡게 됩니다. 제가 이 소스를 64bit머신에서 실행하였으므로 기본으로 잡히는 메모리의 크기가 64bit 즉 8Byte씩으로 되어서 생기는 문제입니다. 이렇게 생각하면 32bit머신에서는 더 많은 메모리를 절약할 수 있겠네요.
 
그리고 위의 예에서 비트로 지정한 필드에 범위를 초과하는 값을 지정하면 gcc에서 Compile시 다음과 같은 경고가 발생하더군요.
 
warning: large integer implicitly truncated to unsigned type
 
 
Creative Commons License
Creative Commons License이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Copyright 조희창(Nicholas Jo). Some rights reserved. http://bbs.nicklib.com
 
번호 제목 글쓴이 날짜 조회 수
38 Windows에서 GetLastError()의 에러 메시지 내용 출력하기 푸우 2013.11.27 16345
37 윈도우즈, 유닉스, C라이브러리 비교 - Securing Windows Objects 푸우 2013.11.27 25152
36 윈도우즈, 유닉스, C라이브러리 비교 - Asynchronous I/O 푸우 2013.11.27 24880
35 윈도우즈, 유닉스, C라이브러리 비교 - Interprocess Communication 푸우 2013.11.27 27232
34 윈도우즈, 유닉스, C라이브러리 비교 - Thread Synchronization 푸우 2013.11.27 26698
33 윈도우즈, 유닉스, C라이브러리 비교 - Threads and Scheduling 푸우 2013.11.27 25440
32 윈도우즈, 유닉스, C라이브러리 비교 - Process Management 푸우 2013.11.27 26814
31 윈도우즈, 유닉스, C라이브러리 비교 - Memory Management, Memory-Mapped Files, and DLLs 푸우 2013.11.27 28715
30 윈도우즈, 유닉스, C라이브러리 비교 - Exception Handling 푸우 2013.11.27 25550
29 윈도우즈, 유닉스, C라이브러리 비교 - File and Directory Management 푸우 2013.11.27 34262
28 BASE64 인코딩 디코딩 file 푸우 2013.11.27 23241
27 mms client file 푸우 2013.11.26 16057
26 The SNIPPETS Portable C++ Source Code Archive file 푸우 2013.11.26 22832
25 The SNIPPETS Portable C Source Code Archive file 푸우 2013.11.26 17251
24 Email 포맷인 eml파일의 필터링을 위한 라이브러리 file 푸우 2013.11.26 17009
23 Linux, Unix에서 라이브러리 만들기 file 푸우 2013.11.26 16535
22 Zlib를 이용한 프로그래밍 푸우 2013.11.26 16844
» Bit Field를 이용한 구조체 크기 줄이기 푸우 2013.11.26 15766
20 C++ 에서 C 함수의 사용하기 푸우 2013.11.26 16442
19 MD5 라이브러리 file 푸우 2013.11.26 14394