C++

[강의] 10월 18일 수업정리

k-codestudy 2024. 10. 20. 04:28

구조체 멤버 맞춤과 구조체의 포인터 사용에 대한 수업을 진행하였다.

 

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 결론 

  1. 구조체 멤버 맞춤은 같은 자료형끼리 붙여서 그룹화하게 되면 메모리 효율이 좋아진다.
  2. 구조체 멤버 맞춤이 있기에 디렉트로 값을 집어넣게 되면 수정하는 경우 의도치 않은 값이 들어갈 수 있기 때문에 안 하는 것을 추천한다. 

 

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