본문 바로가기
프로그래밍/C++

C++의 메모리 관리 : 동적 할당, 스마트 포인터

by 머니테크리더 2023. 9. 29.
반응형

C++의 메모리 관리 : 동적 할당, 스마트 포인터
C++의 메모리 관리 : 동적 할당, 스마트 포인터

🔖 INDEX

     

     

    C++의 메모리 관리

    C++은 개발자에게 메모리 관리에 대한 풍부한 컨트롤을 제공한다. 이러한 자유도는 강력함을 가져다주지만, 잘못 관리될 경우 메모리 누수와 같은 문제점을 야기할 수 있다. 이 글에서는 C++의 동적 할당과 해제, 메모리 누수의 원인 및 해결법, 그리고 스마트 포인터에 대해 살펴볼 것이다.

     

    동적 할당과 해제

    C++에서는 메모리의 동적 할당 및 해제를 수행하기 위한 여러 방법이 제공된다. 그 중 가장 대표적인 방법은 new와 delete를 사용하는 것과, C에서부터 사용되어 온 malloc과 free 함수를 사용하는 것이다.

     

    new와 delete

    C++에서는 new와 delete 연산자를 사용해 동적으로 메모리를 할당하고 해제할 수 있다. new로 메모리를 할당하면, 해당 타입의 기본 생성자가 호출된다.

    int* pInt = new int;      // 동적으로 정수를 위한 메모리를 할당
    *pInt = 10;               
    delete pInt;              // 메모리 해제

    new로 할당된 메모리는 delete를 사용하여 명시적으로 해제해야 한다. 그렇지 않으면 메모리 누수가 발생할 수 있다.

     

    malloc과 free

    malloc과 free는 C 언어에서 메모리 관리를 위해 주로 사용되는 함수들이다. C++에서도 이를 사용할 수 있으나, 주로 C와의 호환성이 필요할 때 사용된다. malloc을 사용하여 메모리를 할당할 때는 할당할 메모리의 크기를 바이트 단위로 지정해야 한다. 또한, malloc로 할당된 메모리는 free를 사용하여 해제해야 한다.

    int* pInt = (int*)malloc(sizeof(int));  // 동적으로 정수를 위한 메모리를 할당
    *pInt = 10;
    free(pInt);                             // 메모리 해제

    malloc과 new의 주요 차이점은 malloc이 메모리만 할당하는 반면, new는 해당 타입의 객체를 메모리에 생성한다는 것이다.

     

    메모리 누수의 원인 및 해결 방법

    메모리 누수는 프로그램이 동적으로 할당한 메모리를 해제하지 않아, 시간이 지남에 따라 점점 더 많은 메모리를 소비하는 현상을 의미한다. 주요 원인은 다음과 같다:

    • delete를 호출하지 않은 경우
    • 할당된 메모리에 대한 포인터를 잃어버린 경우

     

    메모리 누수를 방지하기 위한 방법:

    • 항상 new에 대응하는 delete를 호출한다.
    • 메모리를 할당한 후에는 그 메모리가 더 이상 필요하지 않을 때 즉시 해제한다.
    • 도구를 사용하여 메모리 누수를 감지한다. (예: Valgrind, Sanitizers)

     

     

    스마트 포인터의 중요성과 사용법

    스마트 포인터는 C++에서 동적으로 할당된 메모리의 수명 관리를 자동화하기 위해 사용되는 객체이다. 기본 포인터와는 달리 스마트 포인터는 자동으로 할당된 메모리를 관리해주므로, 메모리 누수와 같은 문제를 효과적으로 방지할 수 있다. C++11부터는 표준 라이브러리에 여러 종류의 스마트 포인터가 포함되어 있다.

     

    std::unique_ptr

    std::unique_ptr은 한 번에 오직 하나의 unique_ptr만이 특정 객체를 소유할 수 있다. 이 포인터가 소멸될 때(예: 스코프 밖으로 벗어날 때) 자동으로 소유하고 있는 메모리를 해제한다.

    • 특징 : 소유권은 이동 가능하지만 복사할 수 없다.
    std::unique_ptr<int> uptr(new int(10));

     

    std::shared_ptr

    std::shared_ptr는 여러 shared_ptr들이 같은 객체에 대한 소유권을 공유할 수 있다. 참조 카운트를 내부적으로 유지하여, 마지막 shared_ptr이 소멸될 때 해당 객체의 메모리가 해제된다.

    • 특징 : 복사와 이동이 모두 가능하며, 복사될 때마다 참조 카운트가 증가한다.
    std::shared_ptr<int> sptr1(new int(10));
    std::shared_ptr<int> sptr2 = sptr1;  // 참조 카운트 증가

     

    std::weak_ptr

    std::weak_ptr는 shared_ptr와 함께 사용되며, 참조 카운트에 영향을 주지 않는다. 주로 순환 참조 문제를 방지하기 위해 사용된다.

    • 특징 : shared_ptr를 생성할 수 있는데, 이때 해당 shared_ptr의 참조 카운트가 증가한다.
    std::shared_ptr<int> sp(new int(10));
    std::weak_ptr<int> wp = sp;

     

    C++의 메모리 관리는 강력한 특징 중 하나다. 그러나 이를 잘못 다루면 메모리 누수와 같은 문제가 발생할 수 있다. 스마트 포인터와 같은 현대 C++의 기능을 활용하면 이러한 문제를 효과적으로 해결할 수 있다.

     

     

    댓글