스마트 포인터
스마트 포인터란?
스마트 포인터는 동적 할당된 객체의 생명 주기를 자동으로 관리하는 객체를 말한다.
기존 포인터
Player* p = new Player();
delete p;
p = nullptr;
스마트 포인터
std::unique_ptr<Player> p = std::make_unique<Player>();
delete를 호출하지 않아도 객체가 필요 없어지는 시점에 자동으로 메모리를 해제한다.
왜 필요한가?
C++에서 가장 위험한 것 중 메모리 관리에 대한 문제가 있다.
- delete를 하지 않으면 메모리 누수 발생
- delete를 두 번 하게 되면 크래시 발생
- 소유권이 불명확하여 중복해서 가리킬 수 있고 누구 하나가 지우고 도망가면 댕글링 포인터가 된다고 함
이런 문제들을 해결하기 위해 스마트 포인터가 설계된 것
스마트 포인트 종류
unique_ptr
하나의 객체를 단 하나의 포인터만 소유한다.
std::unique_ptr<int> p = std::make_unique<int>(10);
이 코드에서 p는 해당 메모리의 유일한 소유자가 되는 것이다.
왜 복사가 안 되는가?
std::unique_ptr<int> a = std::make_unique<int>(10);
std::unique_ptr<int> b = a; // 이러면 X
복사가 허용되면 소유자가 2명이 되는 것이기에 할 수 없다.
move
std::unique_ptr<int> b = std::move(a);
이 경우
- a는 더 이상 소유하지 않는다 (nullptr)
- b가 새 소유자가 된다.
shared_ptr
reference count를 사용하여 같은 객체를 공유한다.
std::shared_ptr<int> a = std::make_shared<int>(10);
std::shared_ptr<int> b = a;
가능하다.
shared_ptr의 문제 - 순환참조
shared_ptr의 치명적인 문제가 있다
class A
{
public:
std::shared_ptr<B> b;
};
class B
{
public:
std::shared_ptr<A> a;
};
해당 코드를 보면 A와 B가 서로를 참조하고 있기에 참조 카운트가 0이 될 수 없다. 즉, 메모리가 절대 해제되지 않는다
weak_ptr
순환 참조의 문제를 해결하기 위해 등장한 것이 이 포인터이다.
std::weak_ptr<int> w = a;
이 포인터는 객체를 소유하지 않는다.
장점
- 참조 카운트를 증가시키지 않음
- 메모리 생명 주기에 영향을 주지 않음
- 댕글링 포인터를 방지
단점
- 사용 전 lock() 필히 확인해야 함
- 객체가 소멸했을 경우도 있기에 이에 대한 예외처리 필요함
즉, 객체의 존재는 확인해야 하지만, 소멸은 막고 싶지 않을 때 사용하면 된다.
핵심 정리
- 하나의 객체의 단 하나만 소유를 하겠다 - unique_ptr
- 여러 곳에서 다 같이 공유를 해야 한다 - shared_ptr
- 순환 참조의 발생을 방지하고 싶다 - weak_ptr
스마트 포인터의 핵심은 "이 객체를 누가 책임질 것인가?"를 명확하게 표현하는 것이 스마트 포인터다.
마무리
동적 할당만 사용하면서 delete의 타이밍이 중요했었는데 스마트 포인터를 오늘 정리하게 되면서 내가 어떠한 객체에 대해 삭제를 직접 하지 않아도 되고 여러 객체를 더 편하게 관리할 수 있는 방법을 알았으니 이제 실제 작성하고 사용해 보면서 적절하게 어떤 때마다 사용해야 되는지를 잘 알고 쓸 수 있게 공부해야겠다
'학습일지 > C와 C++' 카테고리의 다른 글
| C++ 연금술 공방 관리 시스템 구현 과제 (0) | 2026.03.24 |
|---|---|
| C++ 콘솔 RPG 만들기 (0) | 2026.03.19 |
| C++ 인벤토리 시스템 구현 (0) | 2026.03.17 |
| C++ Debugging (0) | 2026.03.16 |
| Moderen C++ (1) | 2026.03.15 |