new/delete 짝 관리 실패 -> 메모리 누수| 타입 | 소유권 모델 | 핵심 |
|---|---|---|
unique_ptr | 단독 소유 | 가장 가볍고 안전한 기본 선택 |
shared_ptr | 공유 소유 | 참조 카운트 기반 |
weak_ptr | 비소유 참조 | 순환 참조 방지/수명 확인 |
std::unique_ptr<Knight> k1 = std::make_unique<Knight>();
std::unique_ptr<Knight> k2 = std::move(k1); // 소유권 이전
auto fileCloser = [](FILE* f) { if (f) fclose(f); };
std::unique_ptr<FILE, decltype(fileCloser)> fp(fopen("a.txt", "w"), fileCloser);
auto k1 = std::make_shared<Knight>();
auto k2 = k1; // 공유 소유
make_shared 권장 이유주의:
shared_ptr<T>(raw)를 여러 번 만들면 제어 블록이 분리되어 이중 delete 위험use_count()는 디버깅 참고용으로만 사용 (동시성 환경에서 로직 의존 금지)weak_ptr는 strong count를 늘리지 않는 비소유 참조입니다.lock()으로 shared_ptr를 임시 복원해 사용합니다.std::weak_ptr<Knight> wp = k1;
if (auto sp = wp.lock()) { // 살아 있을 때만 복원
sp->Attack();
}
| 포인터 | 복사 | 이동 | RefCount | 용도 |
|---|---|---|---|---|
| shared_ptr | ✓ (RefCount++) | ✓ | 참조 | 공유 소유 |
| weak_ptr | ✓ (weak count만) | ✓ | 미기여 | 순환 참조 해결 |
| unique_ptr | ✗ | ✓ | - | 단일 소유 |
shared_ptr끼리 서로 강한 참조를 잡으면 count가 0이 되지 않아 누수가 발생합니다.
한쪽 연결을 weak_ptr로 바꿔 사이클을 끊습니다.
[문제] K1 ──shared_ptr──► K2
▲ │
│ shared_ptr │
└─────────────────┘
→ RefCount 영원히 2, 메모리 누수
[해결] K1 ──weak_ptr────► K2
▲ │
│ shared_ptr │
└─────────────────┘
→ K1 소멸 시 K2 RefCount 0, 정상 해제
enable_shared_from_this (고급, 중요)this로부터 안전한 shared_ptr를 얻고 싶다면 enable_shared_from_this를 사용합니다.
class Knight : public std::enable_shared_from_this<Knight> {
public:
std::shared_ptr<Knight> GetSelf() { return shared_from_this(); }
};
주의:
shared_ptr로 관리되지 않으면 shared_from_this()는 예외/오류std::shared_ptr<Knight>(this)를 수동으로 만들면 제어 블록 분리로 매우 위험| 상황 | 권장 |
|---|---|
| 소유자가 하나 | unique_ptr |
| 여러 시스템이 생명주기를 공유 | shared_ptr |
| 관찰만 하고 소유권은 없음 | weak_ptr |
unique_ptr를 기본 선택으로 권장할까?shared_ptr(this)가 위험한 이유를 제어 블록 관점에서 설명할 수 있는가?