구조체 멤버 맞춤과 구조체의 포인터 사용에 대한 수업을 진행하였다.
1. 구조체 멤버 맞춤
정의 - 구조체의 멤버가 메모리에서 어떻게 정렬되는지를 제어하여, 모듈의 모든 구조에 대해 일관된 메모리 배치를 설정하는 방법이다.
1.1 왜 사용할까?
구조체 멤버 맞춤의 주된 이유는 접근 속도이다.
메모리 블록을 기준으로 멤버를 정렬하여 배열처럼 직접 접근할 수 있게 되어 속도가 향상된다.
즉, 특정 기준에 따라 메모리 블록을 정렬함으로써 접근을 빠르게 하기 위함이 목적이다.
1.2 구조체 멤버 맞춤 기준
C언어 기준 구조체 안에 들어있는 자료형 중 가장 큰 자료형을 기준으로 메모리 블록을 잡게 된다.
1.3 구조체 멤버 맞춤 예시
#include <iostream>
struct S_DATA1
{
int n1;
char c1;
int n2;
char c2;
};
struct S_DATA2
{
int n1;
int n2;
char c1;
char c2;
};
int main()
{
printf("%zd\n", sizeof(S_DATA1));
printf("%zd\n", sizeof(S_DATA2));
}
이 코드에서 S_DATA1과 S_DATA2의 크기를 출력하면 이러한 결과가 나오게 된다.
- S_DATA1 : 16 bytes
- S_DATA2 : 12 bytes
이유 :
- S_DATA1의 경우 int형 (4 bytes)를 기준으로 메모리 블록이 정해진다.
int n1은 4 bytes, char c1은 1byte를 차지하지만 int n2를 위한 4 bytes를 필요로 하기 때문에 3 bytes의 패딩이 추가되기 때문에 16 bytes가 된다. - S_DATA2의 경우 int형 2개가 연속해 있어 8 bytes를 사용하고, char 두 개가 2 bytes를 차지하므로 4 bytes의 패딩이 필요하지 않아 총 12 bytes가 된다.
1.4 결론
- 구조체 멤버 맞춤은 같은 자료형끼리 붙여서 그룹화하게 되면 메모리 효율이 좋아진다.
- 구조체 멤버 맞춤이 있기에 디렉트로 값을 집어넣게 되면 수정하는 경우 의도치 않은 값이 들어갈 수 있기 때문에 안 하는 것을 추천한다.
2. 구조체 포인터
2.1 구조체 포인터 예시
#include <iostream>
struct S_DATA
{
int n1;
int n2;
};
int main()
{
S_DATA sData{};
S_DATA* pData{};
pData = &sData;
(*pData).n1 = 100;
pData->n2 = 50;
printf("%d\n", sData.n1);
printf("%d\n", sData.n2);
}
- (*pData). n1 = 100과 pData->n2는 동일한 의미를 한다.
- (*pData). n1 = 100은 기본적인 문법으로, * 연산자의 우선순위보다. 의 우선순위가 낮아 ()로 묶어 포인터가 가리키는 구조체에 접근한 후 n1에 값을 할당한다.
- pData->n2는 이를 간단하게 사용할 수 있도록 축약한 문법이다.
3. 알아두면 유용한 것과 외워야 할 것
3.1 유용한 것 : #pragma pack(push,1)
- 구조체 멤버의 메모리 정렬을 강제로 설정할 수 있다. #pragma pack(push,1)는 1-byte 정렬을 의미한다.
- 디렉트의 경우 11 이후 기본 구조체 멤버 맞춤은 16 bytes로 설정되어 있으며, 이는 속도의 이점(특히 float의 정렬) 때문이다.
3.2 외워야 할 것
- C++에서는 mem으로 시작하는 함수는 사용하지 않는다.
- 자료형이 명확하지 않은 경우에는 사용할 수 있지만 자료형이 명확한 경우에는 사용하지 않는 것이 좋다
(ex : memset) - 구조체에서 Call by Value로 값을 넘기는 것은 위험한 행동이다
- 큰 구조체의 경우 복사로 인한 메모리 부담이 크기 때문에 주의가 필요하다.
- 하지만 외부 코드에서 변경 가능성이 없는 경우에는 사용하는 경우도 존재한다.
'C++' 카테고리의 다른 글
[강의] 10월 23일 수업정리 (2) | 2024.10.24 |
---|---|
[강의] 10월 22일 수업정리 (1) | 2024.10.23 |
[강의] 10월 17일 수업정리 (1) | 2024.10.18 |
[강의] 10월 16일 수업정리 (1) | 2024.10.17 |
[강의] 10월 15일 수업정리 (1) | 2024.10.16 |