C++

CS) 스마트포인터

준모 2025. 1. 7. 18:24

 

 

 

스마트 포인터(Smart Pointer)는 C++에서 메모리 관리를 자동화하기 위해 사용하는 클래스 템플릿이다.

 

스마트 포인터는 소멸 시 자동으로 동적으로 할당된 메모리를 해제(delete)해 주므로 메모리 누수를 방지하고,

코드의 안정성을 높여준다.

 

스마트 포인터는 C++ 표준 라이브러리 <memory> 헤더에서 제공된다.

 

 

1. std::unique_ptr

  • 특징:
    • 하나의 스마트 포인터만 특정 객체의 소유권을 가질 수 있다 (독점 소유).
    • 복사가 불가능하며, 이동만 가능하다.
    • 객체가 더 이상 필요하지 않으면 자동으로 메모리를 해제한다.

 

 

std::unique_ptr에서 std::move를 사용하여 소유권을 이전할 경우, 소멸자는 발생하지 않는다.

 

단순히 소유권이 이전될 뿐이며, 이전 소유자는 객체에 대한 소유권을 잃고 nullptr 상태가 됩니다.

 

소멸자가 호출되는 시점은 마지막으로 소유권을 가진 unique_ptr이 소멸할 때입니다.

 


 

 

 

2. std::shared_ptr

  • 특징:
    • 여러 스마트 포인터가 같은 객체를 공유할 수 있다 (공유 소유).
    • 내부적으로 참조 카운터를 사용하여, 소유하고 있는 모든 shared_ptr이 파괴되면 메모리를 해제한다.

출력 결과

 

 

std::unique_ptr과 다르게 ' = ' 연산자로 참조개체를 늘릴 수 있다.

 

reset()으로 참조된 개체를 삭제시킬 수 있지만, 아직 다른 참조된 개체가 남아있기 때문에 소멸자가 실행되지 않는다.

 


 

 

3. std::weak_ptr

  • 특징:
    • std::shared_ptr와 함께 사용되며, 참조 카운터에 영향을 주지 않는다.
    • 순환 참조를 방지하는 데 사용된다.
    • shared_ptr이 소유한 객체에 접근할 수 있지만, 직접 메모리를 관리하지 않는다.

출력 결과

 

lock():
weak_ptr을 통해 객체에 접근하려면 lock()을 사용해야 한다. 

lock()은 **shared_ptr**를 반환하며, 객체가 유효하지 않으면 nullptr을 반환한다.

 

expired():
객체가 삭제되었는지 여부를 확인할 수 있다.

참조 카운터가 0이 되면 expired()는 true를 반환한다.

 

use_count():
shared_ptr로 관리되는 객체의 참조 카운트를 확인할 수 있다.

 


 

 

스마트 포인터를 사용하는 이유

  1. 메모리 누수 방지:
    • 동적 할당된 메모리를 자동으로 해제하므로, 프로그래머가 직접 delete를 호출하지 않아도 된다.
    • RAII(Resource Acquisition Is Initialization) 원칙을 따른다.
  2. 안전성:
    • 스마트 포인터는 포인터 소유권 및 생명주기를 명확히 정의해 준다.
    • 소멸된 메모리에 접근하려는 뱅글뱅글 포인터(dangling pointer) 문제를 방지할 수 있다.
  3. 코드 가독성 향상:
    • 명시적인 소유권 이전(std::move) 및 참조 카운터 관리가 쉽다.
  4. 표준 라이브러리 지원:
    • <memory> 헤더에 정의되어 있으므로, 추가 라이브러리를 설치할 필요가 없다.