C++의 스마트 포인터는 일반적인 Raw Pointer의 단점인 메모리 누수(memory leak)와 잘못된 메모리 접근(dangling pointer) 문제를 해결하기 위해 도입된 객체 wrapper이다.
스마트 포인터는 일반적인 포인터처럼 동작하지만, 객체를 소유하고 해당 객체가 더 이상 필요하지 않을 때 자동으로 메모리를 해제하는 기능을 제공한다.
이는 C++의 RAII (Resource Acquisition Is Initialization) 원칙을 활용하여 리소스 관리를 객체의 수명 주기에 묶어 처리함으로써 프로그래머가 수동으로 delete를 호출할 필요를 없애준다.
std::unique_ptr은 배타적 소유권을 관리한다.
즉, 하나의 std::unique_ptr 인스턴스만이 특정 동적 할당 메모리 블록을 소유할 수 있다.
{
// 1. 생성 (가장 권장되는 방식: std::make_unique)
std::unique_ptr<int> ptr1 = std::make_unique<int>(100);
// 2. 소유권 이전 (move)
std::unique_ptr<int> ptr2 = std::move(ptr1); // ptr1은 nullptr이 되고, ptr2가 소유권을 갖는다.
// 3. Raw Pointer 접근
int value = *ptr2;
}
// 4. 범위를 벗어나면 ptr2가 소유한 메모리 자동 해제
std::shared_ptr은 공동 소유권을 관리한다.
여러 shared_ptr 인스턴스가 동일한 동적 할당 메모리를 공유하고 소유한다.
// 1. 생성 (가장 권장되는 방식: std::make_shared)
std::shared_ptr<int> s_ptr1 = std::make_shared<int>(200);
// 2. 복사 (공동 소유, 참조 카운트 증가)
std::shared_ptr<int> s_ptr2 = s_ptr1; // s_ptr1과 s_ptr2 모두 소유하며, 카운트는 2.
// 3. 참조 카운트 확인
// int count = s_ptr1.use_count(); // count == 2
std::weak_ptr은 순환 참조 문제를 해결하기 위해 사용된다.
소유권 없이 shared_ptr 객체를 관찰한다.
lock() 메서드를 통해 shared_ptr로 승격해야 함lock()은 nullptr을 반환std::shared_ptr<int> shared_data = std::make_shared<int>(300);
// 1. weak_ptr 생성 (공유 소유권 객체를 참조)
std::weak_ptr<int> weak_ref = shared_data;
// shared_data = nullptr; // 원본 shared_ptr이 소멸되면 메모리 해제됨
// 2. 메모리 접근을 위한 lock() 및 유효성 검사
if (std::shared_ptr<int> safe_access = weak_ref.lock()) {
// lock()에 성공했으므로 메모리가 유효함
// int value = *safe_access;
} else {
// 원본 shared_ptr이 이미 소멸되어 메모리가 해제되었음
}