ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C/C++ Struct Memory Padding
    프로그래밍/C/C++ 2022. 12. 28. 10:53

    C언어 기반으로 Struct를 사용하여 구조체를 생성 했을 경우 다음과 같은 문제를 본적이 있을 것이다.

     

    일반적으로 내가 할당한(할) 타입의 메모리 크기를 보기위해 다음과 같은 코드를 작성한다.

    #include <stdio.h>
    
    struct MyStruct {
        char ch;        // 1바이트
        char * pCh;     // 4바이트
        int integer;    // 4바이트
    };
    
    int main()
    {
        struct MyStruct custom_type;
        size_t size = sizeof(custom_type);
        printf("Size [%d]Byte ", size);
    }

    구조체를 만들고 해당 구조체의 크기를 알아보기 위해 sizeof(struct MyStruct) 또는 sizeof(custom_type) 을 할시 해당 구조체의 할당된 바이트의 크기정보를 반환해준다.

     

    그럼 위 코드에서는 어떠한 결과가 나오게 되겠는가?

    일반적으로 주석대로 보면 다음과 같이 정리된다.

    char 타입의 경우 1바이트 크기이다.

    char 포인터 타입인 경우 4바이트(32비트 컴파일러 기준) 크기이다.

    int 타입인 경우 4바이트 크기이다.

     

    그럼 다 합치면 9바이트니까 이 구조체의 크기는 9바이트다.

    이러한 결과가 도출될 것이다.

     

    하지만 그렇지 않다, 실제로는 Memory Padding 이라는 것이 존재하게 된다.

    메모리 패딩에 대해서는 몰라도 일반적인 멤버접근 방식으로 쓸 때는 지장은 없지만 알면 더욱 효율적인 코드 작성이 가능하다.

     

    메모리 패딩이 뭐냐 ? 하면 위 구조체의 크기 출력 결과를 먼저 봐야 이해가 가능하다.

    위 프로그램의 출력의 결과는 "Size [12]Byte" 이다.

    멤버변수가 3개이며 각각의 멤버는 32비트 컴파일러 빌드 기준으로 32비트 공간을 할당 받는다.

    그러므로 멤버(char) 자료형의 크기는 비록 1바이트 일 지라도 실제로 구조체 내부적으로 할당된 크기는 각각 4바이트 이기 때문이다.

     

    하지만, 바이트 계산에서 원하는 결과를 얻어낼 수 있는 방법은 존재한다.

    Visual Studio를 기반으로 코드를 작성하는 경우 다음과 같은 "구조체 멤버 맞춤" 옵션을 제어하면 된다.

    설정되어 있는 "기본값"은 컴파일러에 따라 정의된다.

    컴파일러 정보 구조체 멤버 맞춤의 기본값
    x86 4 Byte
    x64 8 Byte

     

    그렇다면 위에 옵션을 제어할 수 있다면, 1바이트로 바꿔서 다시 빌드를 해보자.

     

    자 이제 내용을 보면 처음 주석을 작성한 구조체 멤버의 메모리 크기만큼 동일하게 할당이 되어 총 9Byte라는 결과를 도출했다.

     

     

    그럼 이러한 "구조체 멤버 맞춤" 옵션과 메모리 패딩은 왜 존재하는가 ?

    32Bit CPU와 64비트 CPU의 관계에 따라 달라진다.

    위에 컴파일러별 Packing 크기에 따라 정의된 것 과 같다.

    32bit CPU에서는 메모리에서 하나의 공간을 읽을 때 4바이트 크기 만큼 읽는다.

    64bit CPU에서는 메모리에서 하나의 공간을 읽을 때 8바이트 크기 만큼 읽는다.

     

    메모리 공간 자체는 크기가 어마무시하다.

    가령 본인 PC의 RAM크기가 1GB 라고 가정을 해보자.

    1GB를 4Byte로 나누면 총 1GB를 조회하는데 건너뛰어야 하는 횟수가 정의될 것이다.

    그렇다면, 똑같은 크기를 8Byte로 나눠보자.

    1GB를 조회하는데 4Byte 크기로 건너뛰어야하는 횟수보다 훨씬 적다.

    즉, 메모리 패딩을 맞춤으로써 메모리를 더욱 빠르게 접근하고 찾아낼 수 있다는 것이다.

     

    하지만 이러한 메모리 패딩을 알지 못하면 다음과 같은 세가지 방법중에 한가지만을 선택할 수 밖에 없는 상황이 생긴다.

    1. 이 메모리 패딩을 이용해서 빠르면서 효율적 사용하는 방법
    2. 이 메모리 패딩을 이용해서 속도를 얻고, 메모리 효율성을 최악으로 만드는 방법
    3. 이 메모리 패딩을 이용해서 속도를 낮추고 메모리 효율성을 높이는 방법

     

    이후에 위 세가지 케이스에 대하여 정리를 할 것이다.

    댓글

Designed by Tistory.