63. C++ 스마트 포인터 개념

C++ 스마트 포인터 개념 (unique_ptr, shared_ptr, weak_ptr)

1. 개요

1.1 문서 개요

이 문서는 C++ 표준 라이브러리에서 제공하는 스마트 포인터(unique_ptr, shared_ptr, weak_ptr)의 개념, 역할, 사용 방법에 대해 기록하는 문서입니다. 스마트 포인터는 수동적인 메모리 해제 없이 자원의 소유권과 생명주기를 자동으로 관리할 수 있도록 설계된 도구입니다.

2. 내용

2.1 스마트 포인터 개요

스마트 포인터는 std::unique_ptr, std::shared_ptr, std::weak_ptr로 구성되며, 각각의 클래스는 포인터에 대한 소유권 정책과 참조 카운트 관리 방식이 다릅니다.

2.1.1 주요 목적

  • 메모리 누수 방지
  • 예외 안전성 확보
  • 자원 해제를 자동화(RAII)

2.2 unique_ptr

unique_ptr는 단독 소유권을 가지며, 복사 불가능하고 이동만 가능합니다.

2.2.1 사용 예

#include <memory>
std::unique_ptr<int> uptr = std::make_unique<int>(10);

2.2.2 이동 소유권

std::unique_ptr<int> uptr2 = std::move(uptr); // uptr은 nullptr이 됨

2.2.3 사용자 정의 소멸자

std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("test.txt", "r"), fclose);

2.3 shared_ptr

shared_ptr는 참조 카운트를 통해 여러 객체가 동일 자원을 공유할 수 있도록 설계된 스마트 포인터입니다.

2.3.1 기본 사용 예

#include <memory>
std::shared_ptr<int> sp1 = std::make_shared<int>(100);
std::shared_ptr<int> sp2 = sp1; // 참조 카운트 증가

2.3.2 참조 카운트 확인

sp1.use_count(); // 현재 공유 중인 객체 수

2.4 weak_ptr

weak_ptrshared_ptr가 관리하는 자원을 참조만 하며, 소유권을 갖지 않습니다. 순환 참조 방지에 주로 사용됩니다.

2.4.1 사용 예

std::shared_ptr<int> sp = std::make_shared<int>(200);
std::weak_ptr<int> wp = sp;

2.4.2 lock() 함수로 유효성 확인

if (auto tmp = wp.lock()) {
    // shared_ptr로 일시 승격
}

2.5 순환 참조와 weak_ptr의 역할

2.5.1 순환 참조 문제 예

struct Node {
    std::shared_ptr<Node> next;
};

이 경우 두 객체가 서로를 shared_ptr로 참조하면 참조 카운트가 0이 되지 않아 메모리 누수가 발생할 수 있습니다.

2.5.2 해결 방법

struct Node {
    std::weak_ptr<Node> next;
};

3. 마무리

스마트 포인터는 C++의 메모리 관리에서 수동 해제를 최소화하고 예외 안정성을 높이는 핵심 도구입니다. 각 포인터는 명확한 소유권 정책과 사용 목적을 가지며, 상황에 맞게 적절한 종류를 선택하여 자원의 생명주기를 안전하게 관리할 수 있습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

error: Content is protected !!
위로 스크롤