logo

English

이곳의 프로그래밍관련 정보와 소스는 마음대로 활용하셔도 좋습니다. 다만 쓰시기 전에 통보 정도는 해주시는 것이 예의 일것 같습니다. 질문이나 오류 수정은 siseong@gmail.com 으로 주세요. 감사합니다.

C/C++ struct 패딩(padding) 원리 이해

by lizard2019 posted Mar 04, 2019
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print

구조체(클래스)의 바이트 패딩

 

멤버 변수를 메모리에서 CPU 레지스터로 한번에 읽을 수 있도록

CPU 레지스터의 읽기 블록에 맞춰 정렬하는 컴파일러의 최적화 작업

컴파일러가 패딩을 하지 않아 레지스터가 읽는 블록의 경계에 걸쳐 멤버 변수가 생긴다면

메모리를 읽을 때 두개의 블록을 읽어는 문제가 발생

CPU 레지스터는

32비트 운영체제일때 4바이트

64비트 운영체제일때 8바이트 단위로 메모리를 읽는다

 

구조체를 4바이트 단위로 끊어주는것을 "바이트 패딩" 이라고 한다.

 

아래 예제를 실행하면 쉽게 이해할 수 있다.

 

 
/**
 * Memory align & padding - for struct.
 * compile: gcc memory_align.c
 * execute: ./a.out
 */ 
#include <stdio.h>

// size is 8, 4 + 1, then round to multiple of 4 (int's size),
struct stu_a {
    int i;
    char c;
};

// size is 16, 8 + 1, then round to multiple of 8 (long's size),
struct stu_b {
    long l;
    char c;
};

// size is 24, l need padding by 4 before it, then round to multiple of 8 (long's size),
struct stu_c {
    int i;
    long l;
    char c;
};

// size is 16, 8 + 4 + 1, then round to multiple of 8 (long's size),
struct stu_d {
    long l;
    int i;
    char c;
};

// size is 16, 8 + 4 + 1, then round to multiple of 8 (double's size),
struct stu_e {
    double d;
    int i;
    char c;
};

// size is 24, d need align to 8, then round to multiple of 8 (double's size),
struct stu_f {
    int i;
    double d;
    char c;
};

// size is 4,
struct stu_g {
    int i;
};

// size is 8,
struct stu_h {
    long l;
};

// test - padding within a single struct,
int test_struct_padding() {
    printf("%s: %ld\n", "stu_a", sizeof(struct stu_a));
    printf("%s: %ld\n", "stu_b", sizeof(struct stu_b));
    printf("%s: %ld\n", "stu_c", sizeof(struct stu_c));
    printf("%s: %ld\n", "stu_d", sizeof(struct stu_d));
    printf("%s: %ld\n", "stu_e", sizeof(struct stu_e));
    printf("%s: %ld\n", "stu_f", sizeof(struct stu_f));

    printf("%s: %ld\n", "stu_g", sizeof(struct stu_g));
    printf("%s: %ld\n", "stu_h", sizeof(struct stu_h));

    return 0;
}

// test - address of struct,
int test_struct_address() {
    printf("%s: %ld\n", "stu_g", sizeof(struct stu_g));
    printf("%s: %ld\n", "stu_h", sizeof(struct stu_h));
    printf("%s: %ld\n", "stu_f", sizeof(struct stu_f));

    struct stu_g g;
    struct stu_h h;
    struct stu_f f1;
    struct stu_f f2;
    int x = 1;
    long y = 1;

    printf("address of %s: %p\n", "g", &g);
    printf("address of %s: %p\n", "h", &h);
    printf("address of %s: %p\n", "f1", &f1);
    printf("address of %s: %p\n", "f2", &f2);
    printf("address of %s: %p\n", "x", &x);
    printf("address of %s: %p\n", "y", &y);

    // g is only 4 bytes itself, but distance to next struct is 16 bytes(on 64 bit system) 
    // or 8 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "g", "h", (long)(&h) - (long)(&g));

    // h is only 8 bytes itself, but distance to next struct is 16 bytes(on 64 bit system) 
    // or 8 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "h", "f1", (long)(&f1) - (long)(&h));

    // f1 is only 24 bytes itself, but distance to next struct is 32 bytes(on 64 bit system) 
    //  or 24 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "f1", "f2", (long)(&f2) - (long)(&f1));

    // x is not a struct, and it reuse those empty space between struts, which exists due to padding, 
    // e.g between g & h,
    printf("space between %s and %s: %ld\n", "x", "f2", (long)(&x) - (long)(&f2));
    printf("space between %s and %s: %ld\n", "g", "x", (long)(&x) - (long)(&g));

    // y is not a struct, and it reuse those empty space between struts, which exists due to padding, 
    // e.g between h & f1,
    printf("space between %s and %s: %ld\n", "x", "y", (long)(&y) - (long)(&x));
    printf("space between %s and %s: %ld\n", "h", "y", (long)(&y) - (long)(&h));

    return 0;
}

int main(int argc, char * argv[]) {
    test_struct_padding();
    // test_struct_address();

    return 0;
}

 

TAG •

List of Articles
No. Subject Author Date Views
44 UML - 기본편 ( 기본 표기 형식 및 관계 표현법 ) digipine 2017.10.28 879
43 Visual Studio 단축키 정리 digipine 2024.03.28 37
42 VSCode 에서 한글 특수문자 부분 만 검색하기 file digipine 2021.10.25 676
41 What is Android Repo? and Manual, Download file digipine 2017.11.02 99672
40 Wi-Fi display (miracast) FFMpeg MpegTs Supported digipine 2017.11.02 1303
39 Wi-Fi Display Standard Miracast Protocol Log digipine 2017.11.02 850
38 WIN CE C++ 시리얼 제어 방법 digipine 2017.10.28 631
37 WIN CE, GPS - NMEA protocol - GPS Virtual Driver digipine 2017.10.28 2832
36 Windows API - 안전한 문자열 함수들 digipine 2017.10.28 354
35 Windows에서 SVN 용 폴더 한 번에 삭제하기 digipine 2017.10.29 463
34 WinPCap과 Ethereal, Wireshark 을 이용한 스니핑(Sniffing) digipine 2017.10.29 5429
33 WPA_SUPPLICANT 빌드 방법 digipine 2017.11.01 338
32 WPA_SUPPLICANT 빌드 방법 digipine 2017.11.01 544
31 XCode 사용시 git ignore 로 xcuserstate 충돌 해결하기, .gitignore에 등록했는데도 동작안할때 해결방법 lizard2019 2022.09.25 442
30 xcode xib encountered an error communicating with ibagent-ios 해결 digipine 2022.10.06 384
29 Xcode 없이 맥에 '명령어 라인 도구(Command Line Tools)'를 설치하는 방법 엉뚱도마뱀 2018.12.26 2859
28 XOR Encryption : 단순하면서도 강력한 암호/복호화 기법 digipine 2017.11.02 1739
27 [iOS] Bluetooth로 App을 백그라운드 모드로 실행는 방법 lizard2019 2020.02.11 3528
26 [Linux, OSX] pfctl - Packet FIlter Control 사용법 digipine 2017.11.02 3189
25 [Linux] ubuntu 16.04에 QT Creator 설치하기 digipine 2017.11.02 24348
Board Pagination Prev 1 2 3 4 5 6 Next
/ 6