C++ 동적할당

NYH·2023년 12월 3일

C++

목록 보기
10/17

목차

  1. 동적 할당
  2. 가변 배열
    ?. 문제 풀이


1. 동적 할당

필요성

동적 할당은 프로그램 실행 중 메모리를 동적으로 할당하고 해제하는데 사용됨.

정적 할당은 컴파일 시점에 크기를 결정하고, 프로그램이 실행되는 동안 크기를 변경하기 어렵습니다.

  • 유연한 크기의 자료구조 필요성
    - 프로그램 실행 중에 데이터 크기가 동적으로 변할 때 동적 할당은 필수적입니다.
  • 자원 효율성
    - 정확한 메모리 양을 미리 예측하기 어려운 경우, 동적 할당은 자원을 효율적으로 사용할 수 있게 해줍니다.


메모리 영역

  • 동적 할당의 경우 메모리 영역에서 Heap 영역에 할당됩니다.
  • 프로그램 실행 중 메모리를 동적으로 할당하고 해제하는데 사용되는 영역입니다.


종류

C++에서 동적 할당은 newdelete 키워드를 사용하는 방식, 스마트 포인터를 사용하는 방식으로 나뉩니다. C Style에서는 malloc 을 이용하기도 합니다.

  1. malloc 할당
int main()
{
	// 할당
	int* pInt = (int*)malloc(100);
    // 해제
    free(pInt);
}

mallocvoid* 반환형을 가지고 있습니다.
용량을 정의하면 그에 해당하는 용량을 가지고 있는 주소만을 제공합니다.
즉 해당 공간을 어떻게 사용할지는 사용자가 타입 변환(캐스팅)을 통해 정의해주어야 합니다.

  1. newdelete를 사용한 동적 할당
#include <iostream>

int main() {
    // int 형 동적 할당
    int *intPtr = new int;
    *intPtr = 42;

    std::cout << "Value: " << *intPtr << std::endl;

		// 배열 동적 할당
		char *charPtr = new char[*intPtr];

    // 동적으로 할당된 메모리 해제
    delete intPtr;
		
		delete[] charPtr;

    return 0;
}

c++ 에서 추가된 new 기능을 이용하면
동적 할당시에 타입을 지정해줄 수 있습니다.
delete의 경우 동적으로 할당된 메모리를 해제할 수 있습니다.

  1. 스마트 포인터를 사용한 동적 할당
#include <iostream>
#include <memory>

int main() {
    // int 형 동적 할당 (std::unique_ptr 사용)
    std::unique_ptr<int> intPtr = std::make_unique<int>(42);

    std::cout << "Value: " << *intPtr << std::endl;

    // 메모리는 스마트 포인터가 자동으로 해제

    return 0;
}

다음과 같이 스마트 포인터를 이용하여 동적할당을 수행할 수도 있습니다.


2. 가변 배열

배열의 경우 크기를 중간에 변경하는 것이 불가능합니다.

그러나 프로그램을 수행하다 보면 배열에 담아야 할 데이터가 고정적이지 않고 유동적입니다.

이런 특성을 고려하여 c++에는 가변 배열을 생성할 필요성이 있습니다.


직접 구현

// .h, .hpp

class dynamicArray
{
	private:    
		int* m_array;
    int m_size;
		int m_used;
	public:
		dynamicArray();
		dynamicArray(int size);
		~dynamicArray();
		
		void popBack();
		void pushBack(int data);
		void print();
		int &operator[](int index);
}

// dynamicArray.cc

dynamicArray::dynamicArray() : m_size(10), m_used(0)
{
	 m_array = new int[m_size];
}

dynamicArray::dynamicArray(int size) : m_size(size), m_used(0)
{
	m_array = new int[m_size];
}

dynamicArray::~dynamicArray()
{
	delete[] m_array;
}

void dynamicArray::popBack()
{
	if(m_used == 0)
	{
		std::cout << "array is Empty" << std::endl;
		return;		
	}	
	
	m_used--;
	int* temp = new int[m_used];
	
	for (int i = 0; i < m_used; ++i)
	{		
		temp[i] = m_array[i];
	}
	
	delete[] m_array;
	
	m_array = new int[m_size];
	
	for (int i = 0; i < m_used; i++)        
	temp[i] = m_array[i];     

	delete[] temp;
	return;

	
}

void dynamicArray::push_back(int data)
{
	
	if(this->m_size > this->m_used)
	{
		this->m_array[this->m_used] = data;
	}
	else
	{
		int* temp = new int[this->m_size];
		
		for (int i = 0; i < m_used; ++i)
		{
			temp[i] = this->m_array[i];
		}	
		
		delete[] this->m_array;
		
		this->m_array	= new int[m_size * 2];
		
		for (int i = 0; i < m_used; ++i)
		{
			m_array[i] = temp[i];
		}

		m_array[m_used] = data;
		
		delete[] this->temp;
	}
	
	this->m_used++;
}

int& dynamicArray::operator[](int index){    
			return this->m_array[index];
}

가변 배열의 경우 꼭 필요한 크기 만큼 크기를 지정하거나, 필요한 크기보다 조금 더 크게 지정 하는 것이 메모리 자원을 아낄 수 있습니다.


std::vector

c++ 에서는 가변배열로 std::vector를 지원합니다.

std::vector는 배열크기를 가변적으로 사용할 수 있는 컨테이너 입니다.

소년 코딩 std::vector


?. 문제 풀이

문제 1.

정수 배열을 동적으로 할당하고 사용자로부터 배열의 크기를 입력 받아 값을 저장하고 출력하는 프로그램을 작성하세요. 그 후, 동적으로 할당한 메모리를 반드시 해제하세요.


문제 2.

두 개의 정수를 동적으로 할당하고 사용자로부터 값을 입력 받아 두 값을 더한 결과를 출력하는 프로그램을 작성하세요. 그 후, 동적으로 할당한 메모리를 반드시 해제하세요.


문제 3.

std::vector를 사용하여 동적으로 크기가 변하는 정수 배열을 구현하세요. 배열에 값을 추가하고 제거하는 예제를 작성하세요.

profile
그냥 해라

0개의 댓글