📚책읽기

[C++] 가변배열(동적할당 활용)

공대 컴린이 2022. 4. 4. 21:57
728x90
  • 가변 배열의 구현
    이전 시간에 공부한 동적 할당 개념을 활용하여 'int형 가변 배열'을 직접 구현해보았다.
    - Arr.h 헤더 파일 및 Arr.cpp 파일 생성

  • Arr.h 헤더 파일의 생성
  • 가변 배열의 필수 구조체 멤버
// int형 가변배열
typedef struct _tabArr
{
	// 필수 멤버 3가지
	int* pInt;
	int iCount;
	int iMaxCount;
}tArr;
  • 가변 배열을 구현하기 위해 헤더 파일에 구조체를 생성하였다.
    구조체 필수 멤버로는 배열을 저장할 포인터 변수(pInt), 현재 배열의 요소 수를 확인할 변수(iCount), 배열의 최대 크기 변수(iMaxCount)까지 3가지가 필요하다.

  • 가변 배열 필수 함수
// 배열 초기화 함수
void InitArr(tArr* _pArr);

// 배열의 공간 추가 확장 함수
// void Reallocate(tArr* _pArr); 
// 이 함수는 main함수에서 직접 호출하지 못하도록 헤더파일에선 제거하였다. 
// Arr.cpp파일 내부에선 자체적으로 호출하여 사용한다.

// 데이터 추가 함수
void PushBack(tArr* _pArr, int _iData);

// 배열 메모리 해제 함수
void ReleaseArr(tArr* _pArr);
  • 가변 배열을 구현하기 위해선 구조체의 멤버 변수를 초기화하기 위한 배열 초기화 함수(InitArr)와 배열에 데이터를 추가하는 함수(PushBack), 할당한 배열의 메모리를 해제하는 함수(ReleaseArr)가 필요하다. 
  • 가변 배열인 만큼 현재 배열의 크기보다 더 많은 데이터를 저장해야 할 땐 배열의 공간을 추가적으로 확장하기 위한 함수(Reallocate)가 필요하다. 하지만 해당 함수는 main함수에서 직접 선언할 필요가 없이 데이터를 추가하는 경우 배열의 크기를 검사하는 조건문에서 수행하기 때문에 헤더 파일에서는 제거해 주었다.

  • Arr.cpp 파일의 생성
  • 헤더 파일에 선언된 함수의 내용을 차례차례 구현해보았다.
#include "Arr.h"

#include <iostream>

// 배열 초기화 함수
void InitArr(tArr* _pArr) 
{
	_pArr->pInt = (int*)malloc(sizeof(int)*2);
	_pArr->iCount = 0;
	_pArr->iMaxCount = 2;
}

// 배열의 공간 추가 확장 함수 (재할당)
void Reallocate(tArr * _pArr)
{
	// 1. 2배 더 큰 공간을 동적할당한다.
	int* pNew = (int*)malloc(_pArr->iMaxCount * 2 * sizeof(int));
	// 새로운 메모리 공간을 지역변수 pNew에 먼저 저장시켜둔다.
	// pInt에 바로 재할당을 하면 pInt에 원래 할당되어있던 주소는
	// 더이상 사용되지 않고 사라지게 된다.

	// 2. 기존 공간에 있던 데이터들을 새로 할당한 공간으로 복사시킨다.
	for (int i = 0; i < _pArr->iCount; ++i)
	{
		pNew[i] = _pArr->pInt[i];
	}

	// 3. 기존 공간은 메모리 해제
	free(_pArr->pInt);

	// 4. 배열이 새로 할당된 공간을 가리키게 한다.
	_pArr->pInt = pNew;

	// 5. MaxCount 변경점 적용
	_pArr->iMaxCount *= 2;
}

// 데이터 추가 함수
void PushBack(tArr * _pArr, int _iData)
{
	// 힙 영역에 할당한 공간이 다 참
	if (_pArr->iMaxCount <= _pArr->iCount) 
	{
		// 재할당
		Reallocate(_pArr);
	}

	// 데이터 추가
	_pArr->pInt[_pArr->iCount++] = _iData;
}

// 배열 메모리 해제 함수
void ReleaseArr(tArr * _pArr)
{
	free(_pArr->pInt);
	_pArr->iCount = 0;
	_pArr->iMaxCount = 0;
}
  • 가장 눈여겨보아야 하는 곳은 가변 배열인 만큼 배열의 크기를 확장하는 Reallocate 함수이다.
    위 코드에서는 데이터를 추가할 때 배열의 크기가 다 찼으면 현재 크기보다 2배 큰 크기로 메모리를 재할당하도록 구현하였다. 함수의 구현은 단계별로 주석을 자세히 작성해 놓았기 때문에 생략한다.
  • main 파일에서의 사용 예시
#include <iostream>
#include "Arr.h"

int main()
{
	tArr s1 = {};
    
    InitArr(&s1);

	for (int i = 0; i < 10; ++i)
	{
		PushBack(&s1, i);
	}

	for (int i = 0; i < s1.iCount; ++i)
	{
		printf("%d\n", s1.pInt[i]);
	}

	ReleaseArr(&s1);
    
    return 0;
}
  • main 함수의 실행 결과, 초기 배열의 크기를 2로 설정하였지만 0부터 9까지 10개의 숫자가 모두 정상적으로 출력됨을 확인하였다.

 

728x90