struct Bonfire {
bool bIsSleeping;
int nMemberCount;
bool bIsHappy;
bool bCanJoinNow;
};
다음 구조체의 크기는 몇일까?
우리가 알고 있는 지식으로는 bool이 1바이트, int는 4바이트이다
따라서 bool x3 + int x1로 7바이트라고 생각할 수 있다
그렇다면 돌려보자
int main() {
Bonfire fire;
std::cout << "Size of Bonfire: " << sizeof(fire) << std::endl;
return 0;
}

이게 왠걸
거의 2배인 12바이트가 할당되어버렸다
왜 그럴까?
첫번째로는 애초에 7바이트라는 사이즈만 할당할 수 없다
CPU에서는 값을 읽을때 4바이트로 정렬되어있다면 값을 한번에 읽을 수 있다
그렇기 때문에 컴파일러는 ABI(Application Binary Interface)라고 하는 규약을 따라 4바이트씩 데이터를 정렬한다
따라서 모든 데이터들은 1-4-8-16... 기준으로 할당된다
자 그럼 7이 안 나오는건 이해가 됐다
그럼 8이 나와야지 왜 12가 나오는걸까?
그 이유는 값을 정렬할때 패딩(padding)이라는 것이 들어가기 때문이다
만약 저 구조체의 메모리 레이아웃을 그려본다고 하자
cpp
b: bool, i: int
[b][ ][ ][ ] / [ ][ ][ ][ ] / [ ][ ][ ][ ]
우선 bIsSleeping에 해당하는 1바이트 bool을 삽입하였다
이 제 뭐 하 지 ?
다음으로는 4바이트 int를 삽입해야하는데 b 바로 다음에 넣게된다면 정렬 규칙이 깨져버리게 된다
따라서 컴파일러는 3바이트의 패딩값을 b다음에 먼저 삽입한다
그리고 그 후에 4바이트 int를 넣는다
b: bool, i: int, p: padding
[b][p][p][p] / [i][i][i][i] / [ ][ ][ ][ ]
벌써 8바이트나 먹었다
이제 bool이 2개 남았다
먼저 삽입해보자
b: bool, i: int, p: padding
[b][p][p][p] / [i][i][i][i] / [b][ ][ ][ ]
이제 1바이트 bool을 하나 더 삽입해야하지만
남은 크기를 보니 3바이트라는 무려 3배나 더 되는 크기가 남아있다
따라서 컴파일러는 b바로 다음에 bool을 하나 삽입한다
b: bool, i: int, p: padding
[b][p][p][p] / [i][i][i][i] / [b][b][ ][ ]
그리고 구조체 자체의 변수가 더 없기 때문에 이 또한 4바이트씩 맞춰줘야한다
고로, 마지막에 패딩을 넣는다
b: bool, i: int, p: padding
[b][p][p][p] / [i][i][i][i] / [b][b][p][p]
이렇게 완성된구조체의 메모리 레이아웃은 총 12바이트를 할당받고 있다
vs에서도 확인해보자

근데 이 메모리 구조를 보고있자니
내 안에서 치밀어오르는 이 화를 감출 수가 없다
아니 내가 쓰는건 7바이트 뿐인데
총 공간은 12바이트나 먹고 있다
무려 5바이트나 놀고 있는 것이다
고작 5바이트라고 생각할 수 있지만
이러한 객체가 굉장히 많아진다면
전체 용량에 약 41%를 낭비하고 있는거다
따라서 우리는 아주 살짝의 터치로 이를 보완할 수 있다
struct Bonfire {
int nMemberCount;
bool bIsSleeping;
bool bIsHappy;
bool bCanJoinNow;
};
끝이다
bool을 한곳으로 모아두면 메모리 레이아웃은

이렇게 바뀌게 된다
총 크기 8바이트에 놀고 있는 용량도 1바이트밖에 안된다
이렇게 단순히 변수의 순서만으로도 최적화에 도움이 될 수 있다
'거창하지 않지만 중요한 개발 잡담' 카테고리의 다른 글
| Let's Groove - TCP와 UDP (0) | 2026.03.07 |
|---|---|
| Nameless - 좋은 이름을 짓는 방법 (0) | 2025.12.06 |
| Still Alive - RAII에 대하여 (0) | 2025.07.21 |