본문 바로가기

C++

C++ 동적할당

 

1. 동적 할당

 

필요성

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

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

동적 할당은 다음과 같은 이유로 인해 사용됩니다.

 

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

메모리 영역

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

 

종류

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

 

 

 

malloc 할당

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

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

 

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의 경우 동적으로 할당된 메모리를 해제할 수 있습니다.

 

스마트 포인터를 사용한 동적 할당

#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는 배열크기를 가변적으로 사용할 수 있는 컨테이너 입니다.

 

 

문제 풀이

문제 1.

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



문제 2.

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



문제 3.

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

'C++' 카테고리의 다른 글

C++ 자료구조 구현 Red-Black Tree  (0) 2024.11.30
C++ 클래스  (0) 2024.05.12
C++ 컴파일 과정  (0) 2024.04.21
C++ Const 정확도(Const Correctness)  (0) 2024.04.06
C++ 연산자  (0) 2024.02.28