구조체의 크기는 구조체를 구성하는 요소들에 의해 정해 집니다.
하지만 크기를 출력해보면 예상한 값과 다르게 나올때가 있는데, 그 이유와 구조체의 구조에 대해 알아보겠습니다.
struct Packet00{
char flags; // 1byte
short count; // 2byte
int msg; // 4byte
}
sizeof(Packet00); // 8byte
위 구조체의 크기는 어떻게 정해졌을 까요?
구조체는 구조체가 포함하고 있는 요소들중 가장 큰 값을 기준으로 그 값의 배수만큼의 크기를 가집니다.
Packet 구조체의 요소들의 크기를 더한 값은 7byte입니다.
하지만 요소들 중 크기가 가장 큰 int가 4byte의 크기를 가지기 때문에 총 크기는 그 배수인 8byte로 정해집니다.
또 다른 예를 들어보겠습니다.
struct Packet01{
char flags; // 1byte
int msg; // 4byte
short count; // 2byte
}
sizeof(Packet01); // 12byte
Packet00와 Packet01이 다른 점은 자료의 배치 뿐입니다.
그렇다면 위와 같이 8byte가 나올 것이라 예상 할 수 있지만 실제로는 12byte가 나오게 됩니다.
Packet01은 메모리에 아래와 같이 적재됩니다.
이렇게 빈공간이 생기는 이유는 CPU가 자료형을 저장할때 효율을 위해 자료형 크기의 배수에 해당하는 주소에 위치시키기 때문입니다.
따라서 1byte인 char형은 메모리 어디에나 적재가 가능하고, short형은 2의 배수 주소에, int 형은 4의 배수 주소에만 적재 할 수 있습니다.
위 규칙에 따라 구조체의 요소들을 순서대로 배치하면 구조체의 크기를 쉽게 유추할 수 있습니다.
몇 가지 예를 적어보겠습니다.
struct Packet02{
char flags; // 1byte +
short count; // 2byte +
int msg; // 4byte +
int msgID; // 4byte = 11 byte
}
sizeof(Packet02); // 12byte
struct Packet03{
char flags; // 1byte +
int msg; // 4byte +
int msgID; // 4byte = 9 byte
}
sizeof(Packet03); // 12byte
struct Packet04{
char flags; // 1byte +
char flags2; // 1byte +
char flags3; // 1byte = 3 byte
}
// 가장 작은 구성요소의 크기가 1byte이므로 1byte의 배수로 크기가 정해집니다.
sizeof(Packet04); // 3byte
struct Packet05{
char flags; // 1byte +
short flags2; // 2byte = 3 byte
}
// Packet04와 구성 요소의 총 길이는 같지만 가장 작은 요소가 2byte이므로 구조체의 크기가 달라집니다.
sizeof(Packet05); // 4byte
struct Packet06{
char flags; // 1byte +
long long ip1; // 8byte +
long long ip2; // 8byte = 17 byte
}
sizeof(Packet06); // 24byte
구조체 안에 구조체가 있을 경우에는 모든 내부구조체의 원소중 가장 큰 값을 기준으로 크기가 할당됩니다.
(내부 구조체가 24byte라고 외부 구조체의 크기가 24byte의 배수가 되지는 않습니다.)
struct Packet05{
char flags; // 1byte +
short flags2; // 2byte = 3 byte
}
sizeof(Packet05); // 4byte
struct Packet06{
char flags; // 1byte +
long long ip1; // 8byte +
long long ip2; // 8byte = 17 byte
}
sizeof(Packet06); // 24byte
struct Packet07{
Packet05 p5; // 4byte +
Packet06 p6; // 24byte = 28 byte
}
// 가장 큰 원소는 long long(8byte)입니다.
sizeof(Packet07); // 32byte (8byte*4)
Packet06의 원소중 8byte 크기의 long long 형이 있으므로, CPU는 Packet06의 시작 주소를 8의 배수로 지정합니다.
구조체의 형태는 그대로 유지됩니다.
'메모장 > C++' 카테고리의 다른 글
[C++/etc] 키워드 사전 (수정중) (0) | 2022.11.23 |
---|---|
[C++] 스마트 포인터 메모 (0) | 2022.11.17 |
[c++] async 테스트 (0) | 2021.12.15 |
[C, C++] 표준 입출력 실험 (scanf) (0) | 2019.09.03 |
C++/STL List를 순회하는 방법 (0) | 2019.05.24 |