C++ - 구조체 포인터, 동적할당

이강민·2023년 8월 24일

C++

목록 보기
14/22
post-thumbnail

구조체 포인터

구조체도 마찬가지로 포인터 변수를 생성할 수 있다.
구조체의 포인터 변수를 만드는 방법은 다음과 같다.

typedef struct _tagMyst {
	int a; //맴버
	float f;
}MyST;

int main(){
	
    // 구조체 초기화
    MyST s = {10, 2.0];
    
    // 포인터 변수 생성
    MyST* pST = &s;
	return 0; 
}

위와 같이 구조체도 포인터 변수를 지정할 수 있다. 포인터 변수라는 것을 타입을 명시하고 구조체를 초기화 시킨 변수의 주소값을 할당하면 된다. 구조체 포인터를 생성하면 일반적인 포인터 변수와 동일하게 역참조하여 값을 가져올 수있다.
마찬가지로 값을 할당 할 수 있는데 다음과 같다.

typedef struct _tagMyst {
	int a; //맴버
	float f;
}MyST;

int main(){
	
    // 구조체 초기화
    MyST s = {10, 2.0];
    
    // 포인터 변수 생성
    MyST* pST = &s;
	// 역참조하여 값을 할당.
    // 포인터 변수의 연산을 먼저 하도록 유도하기 위해 괄호를 사용
    (*pST).a = 100;
	//참조연산자를 활용하여 값을 할당하거나 출력할 수 있다.
    pST->f = 3.14f;

	printf("%d", (*pST).a);

	printf("%d", pST -> a);
return 0; 
}

포인터 변수이기에 *pST는 첫번째 값인 a 맴버변수를 가르킨다.

동적할당

동적할당이란 프로그램 실행 중에 메모리를 할당하는 것을 동적 할당(dynamic allocation) 또는 런타임 메모리 할당이라고 한다. 동적 할당은 프로그램을 작성할 때, 컴파일러가 정적으로 메모리를 할당하여 사용하는 것과는 달리, 실행 중에 필요할 때 메모리를 동적으로 할당하여 사용하는 방식이다.

  • 런타임 중에 대응 가능
  • 개발자가 직접 메모리를 관리해야함.

동적할당은 매개변수의 크기만큼 힙 영역을 생성하고 주소를 return 한다.
요청한 만큼 메모리를 할당할 뿐이고 포인터 변수가 그 타입을 결정한다.

malloc

new 연산자를 통한 동적할당도 있지만 다음에 알아보고 지금은 iostream 라이브러리의 malloc함수로 동적할당을 살펴보겠다.
malloc함수는 void 타입으로 어떤 타입으로든 받을 수 있고 타입캐스팅을 통해서 각 타입에 맞게끔 포인터변수를 할당하게 된다.

int* pMal = (int*)malloc(100);
float* pF = (float*)malloc(4);
//float는 8바이트 타입인데 4바이트만 할당하였기에 4바이트가 넘어가면 데이터가 손실된다.
// 포인터 변수처럼 값을 할당할 수 있다., 빈 메모리 주소라고 생각하면 쉽다.
*pF = 2.4f;
int* pI = (int*)pF;
printf("%d", *pI);
//그 수를 int타입으로 다시 포인팅 하면 이진수 부동소수 부분을 int로 해석하여
// 큰 정수값이 나오게 된다.

malloc함수를 이용하여 주소값을 가지고 타입 캐스팅을 통해 주소값을 해석한다.
메모리 동적할당은 힙영역에서 이루어지는데 주소값을 생성하고 사용하고나서 메모리를 해제하지 않으면 메모리 누수가 발생할 수 있다.

// 사용자로부터 int타입의 값을 받는다.
int iInput = 0;
scanf_s("%d", &iInput);
// 포인터 변수 초기화
int* pInt = nullptr;
// 사용자 입력값에 따라 조건식 만족여부 검사
if (100 == iInput) {
// 사용로부터 int타입을 받고 int타입의 포인터 변수에 저장하기에 int타입으로 캐스팅하였다.
	pInt = (int*)malloc(100);
}

메모리를 해제하지 않으면 애플리케이션의 크기가 커질 수 록 메모리 누수용량이 커지고 결국 메모리 부족현상이 발생할 수 있다.
따라서 포인터변수가 비어있는 값이 아니라는 간단한 조건식 검사를 통해 free함수를 이용하여 메모리를 해제한다.

if (nullptr != pInt) {
	free(pInt);
}

메모리 누수 위험에도 불구하고 메모리를 관리하는 동적할당을 사용하는 이유는 링크드나 리스트, 트리 같은 자료구조를 구현할 때 배열에 할당한 메모리 잔여 크기만큼 성능이 떨어지는 단점이 있다. 메모리를 동적으로 관리함으로써 애플리케이션의 성능이나 유연성을 확보할 수 있다.

profile
AllTimeDevelop

0개의 댓글