구조체 크기가 멤버 크기 합과 다른 이유는 정렬과 패딩 때문입니다.
- 구조체 크기가 왜 예상보다 큰지 확인하고 싶다
- 필드 순서를 바꾸면 왜 크기가 줄어드는지 다시 보고 싶다
- 구조체를 그대로 파일/네트워크에 쓰면 왜 위험한지 설명해야 한다
숏컷 코드
struct Padded {
char a;
int b;
char c;
};문법
패딩은 컴파일러가 임의로 장난치는 공간이 아니라, CPU가 특정 타입을 더 정렬된 주소에서 읽기 쉽도록 넣는 빈칸입니다.
struct Bad {
char a;
int b;
char c;
};
struct Better {
int b;
char a;
char c;
};이 구조체는 멤버 크기만 더한 값처럼 보이지 않을 수 있습니다. 이유는 CPU가 특정 타입을 정렬된 주소에서 읽는 것을 선호하기 때문입니다.
그래서 컴파일러는 중간에 보이지 않는 패딩 바이트를 넣습니다.
즉 구조체를 설계할 때는 의미뿐 아니라 정렬 비용도 같이 보게 됩니다.
정렬과 직렬화
size_t offset = offsetof(struct Padded, b);이 값으로 특정 필드가 실제로 어디에 놓였는지 알 수 있습니다. 바이너리 포맷이나 저수준 디버깅에서 특히 유용합니다.
자주 하는 오해
구조체를 메모리 그대로 파일이나 소켓에 써도 된다고 생각하는 것입니다.
- 패딩이 같이 들어갈 수 있다
- 플랫폼/컴파일러에 따라 배치가 달라질 수 있다
즉 구조체는 "그냥 직렬화 버퍼"가 아니라, 메모리 레이아웃이 구현 세부사항을 포함하는 타입입니다.
체크포인트
- 구조체 크기 = 멤버 합이 아닐 수 있음
- 패딩은 정렬 때문에 생김
- 큰 필드를 앞에 두면 줄어들 수 있음
- 바이너리 직렬화는 필드 단위로 보는 편이 안전
주의할 점
#pragma pack으로 패딩을 강제로 없애는 것은 마지막 수단에 가깝습니다. 메모리 배치를 맞출 수는 있지만, 접근 비용과 이식성 부담이 같이 따라오기 때문에 "네트워크/파일 포맷과 정확히 맞춰야 하는 경우"가 아니면 먼저 설계를 다시 보는 편이 좋습니다.
참고 링크
1 sources