Application/기초

[기초] C++ 유니언과 비트필드 (UNION & BitField)

devsalix 2024. 4. 24. 07:39
728x90

 

컴퓨터 프로그래밍에서 메모리는 매우 중요한 자원입니다.
특히 임베디드 시스템이나 메모리 사용에 제약이 있는 환경에서는 각 바이트를 효율적으로 사용하는 것이 필수적입니다.

C++에서는 'union'과 'struct'를 활용하여 비트 단위로 메모리를 제어할 수 있는 방법을 제공하며,

이를 비트 필드라고 합니다.

이번 포스팅에서는 C++의 비트 필드 사용법과 이를 활용한 예시를 살펴보겠습니다.

 


비트 필드 정의

 

비트 필드는 구조체 내에서 각 멤버 변수가 차지하는 비트 수를 명시적으로 지정하는 기법입니다.

이를 통해 변수에 할당된 메모리 크기를 정밀하게 조절할 수 있어 메모리 사용을 최적화할 수 있습니다.

 

비트 필드 사용법

 

비트 필드는 보통 'struct' 또는 'union' 내부에서 사용됩니다.

간단한 예로, 여러 개의 불리언 값을 저장하는 경우 각 불리언 값에 1비트만 할당하여

메모리 사용을 최소화할 수 있습니다.

 

#include <iostream>
using namespace std;

struct BitField {
    unsigned int isReady : 1;
    unsigned int isSet : 1;
    unsigned int hasData : 1;
};

int main() {
    BitField status;
    status.isReady = 1;
    status.isSet = 0;
    status.hasData = 1;

    cout << "Status: "
         << "isReady=" << status.isReady
         << ", isSet=" << status.isSet
         << ", hasData=" << status.hasData << endl;

    return 0;
}

 

이 예제에서 'BitField' 구조체는 3개의 멤버를 가지고 있으며, 각각 1비트만 차지합니다.

따라서 이 구조체는 총 3비트의 메모리만 사용하게 됩니다.

 

'union'을 이용한 비트 필드

 

'union'을 이용하면 여러 멤버들이 동일한 메모리 위치를 공유할 수 있습니다.

비트 필드와 결합하면, 다양한 데이터를 효과적으로 표현할 수 있습니다.

 

#include <iostream>
using namespace std;

union DeviceStatus {
    struct {
        unsigned int isOn : 1;
        unsigned int hasError : 1;
        unsigned int reserved : 30; // 나머지 비트는 예약
    } bits;
    unsigned int rawValue; // 전체 값을 한 번에 접근할 수 있도록 함
};

int main() {
    DeviceStatus status;
    status.rawValue = 0; // 초기화
    status.bits.isOn = 1;
    status.bits.hasError = 0;

    cout << "Device Status: " << status.rawValue << endl;

    return 0;
}

 

위 코드에서는 'DeviceStatus' 유니온을 통해 각 비트 필드에 접근하거나

'rawValue'를 통해 전체 값을 한 번에 조작할 수 있습니다.

 

비트 필드의 주의점

 

비트 필드를 사용할 때는 몇 가지 주의해야 할 점이 있습니다

 

  • 비트 필드의 크기는 보통 'unsigned int' 또는 'int'로 정의되어야 합니다.
    다른 유형은 표준에서 정의하지 않았을 수 있습니다.

  • 비트 필드의 순서와 메모리 패딩은 컴파일러에 따라 다를 수 있으므로 플랫폼 간 호환성에 주의해야 합니다.

  • 비트 필드의 사용은 가독성을 저하시킬 수 있으므로,
    성능과 메모리 최적화가 필수적인 경우에만 사용하는 것이 좋습니다.

  • 최적화를 위해서는 구조체 작성 전 #pragma pack(1) 선언 후
    구조체 작성 후 #pragma pack() 으로 설정을 풀어줘야 합니다
    참조 : https://devsalix.tistory.com/215
 

[기초] C++ 메모리 패킹 (pragma pack)

메모리 패킹은 데이터 구조체의 각 멤버가 메모리 상에서 최소한의 공간만을 차지하도록 강제하는 기법입니다.C++에서는 '#pragma pack(1)' 지시어를 사용하여 구조체, 클래스, 또는 유니온의 패딩을

devsalix.tistory.com

 

마무리

 

C++에서의 비트 필드는 메모리 절약과 데이터 구조의 효율적인 표현을 가능하게 합니다.

특히 임베디드 시스템이나 자원이 제한된 환경에서 유용하게 사용될 수 있습니다.

그러나 이 기법의 복잡성과 구현상의 주의점을 잘 이해하고 사용해야 합니다.

 

 


제 글이 도움이 되셨다면 댓글 & 공감 부탁드려요 😀

 

 
728x90
반응형