728x90
반응형
C++11
에서 스마트 포인터(std::unique_ptr
,std::shared_ptr
,std::weak_ptr
)는 동적 메모리 관리를 자동으로 수행하지만, 특정 시점에 명시적으로 내부 리소스를 해제해야 하는 경우가 있습니다.- 이를 위해
reset()
메서드를 사용할 수 있습니다. 이 글에서는 각 스마트 포인터의reset()
동작을 예제 코드와 함께 설명하겠습니다.
-
std::unique_ptr
은 단독 소유권 을 갖는 스마트 포인터로,reset()
을 호출하면 내부 리소스를 해제하고nullptr
상태가 됩니다. -
cpp
#include <iostream> #include <memory> int main() { std::unique_ptr<int> up = std::make_unique<int>(42); // 42를 가리키는 unique_ptr 생성 up.reset(); // 내부 리소스 해제 후 nullptr로 설정 if (up == nullptr) { std::cout << "맞아요! nullptr 상태입니다." << std::endl; } }
reset()
이 호출되면 내부 객체가delete
되어 메모리가 해제됩니다.unique_ptr
은 소유권을 단독으로 가지므로, 다른 곳에서 해당 객체를 사용할 수 없습니다.
-
std::shared_ptr
은 여러 개의shared_ptr
이 동일한 객체를 공유할 수 있으며, 참조 카운트(reference count
) 를 사용하여 마지막 소유자가 객체를 해제합니다. -
reset()
을 호출하면 해당shared_ptr
만 소유권을 포기하고 참조 카운트가 감소합니다. -
cpp
#include <iostream> #include <memory> int main() { auto sp1 = std::make_shared<int>(42); // sp1 생성, 참조 카운트: 1 auto sp2 = sp1; // sp1는 참조 카운트 증가 1에서 2로 증가. sp2는 sp1과 동일. std::cout << "sp1.use_count(): " << sp1.use_count() << std::endl; // 2 std::cout << "sp2.use_count(): " << sp2.use_count() << std::endl; // 2 sp1.reset(); // sp1은 nullptr 상태가 되고 참조 카운트 1에서 0으로 감소 // sp2는 참조 카운트 2에서 1로 감소 std::cout << "sp2.use_count() after sp1.reset(): " << sp2.use_count() << std::endl; // 1 }
reset()
이 호출되면 해당shared_ptr
이 소유한 객체에 대한 소유권을 포기합니다.- 단, 다른
shared_ptr
이 같은 객체를 참조 중이면 객체는 삭제되지 않고, 참조 카운트만 감소합니다. - 마지막
shared_ptr
이reset()
을 호출하거나 범위를 벗어나면 객체가 삭제됩니다.
-
std::weak_ptr
은std::shared_ptr
이 관리하는 객체를 "약한 참조(weak reference
)"로 저장하며, 참조 카운트를 증가시키지 않습니다. -
reset()
을 호출하면weak_ptr
이 참조하는 객체에 대한 연결이 해제됩니다. -
cpp
#include <iostream> #include <memory> int main() { std::shared_ptr<int> sp = std::make_shared<int>(42); // shared_ptr sp 생성. sp의 참조 카운트 1 std::weak_ptr<int> wp = sp; // weak_ptr wp 생성 (참조 카운트 영향 없음) std::cout << "shared_ptr use_count: " << sp.use_count() << std::endl; // 1 if (auto locked = wp.lock()) { // weak_ptr를 shared_ptr로 변환하여 사용 가능 std::cout << "locked value: " << *locked << std::endl; // 값 42 출력 } else { std::cout << "Object expired" << std::endl; } wp.reset(); // weak_ptr wp의 참조 해제 (weak_ptr의 reset()해도 참조된 shared_ptr sp의 참조 카운트는 영향 없음 if (auto locked = wp.lock()) { // false std::cout << "locked value: " << *locked << std::endl; } else { std::cout << "After wp.reset(), object not accessible." << std::endl; } sp.reset(); // shared_ptr sp의 리소스 해제 (객체 삭제) // weak_ptr wp가 참조하던 객체(sp)가 삭제되었는지 확인 if (wp.expired()) { // true std::cout << "After sp.reset(), object has expired." << std::endl; } else { std::cout << "Object still alive." << std::endl; } }
weak_ptr
의reset()
은 내부 참조를 해제하지만, 객체의 생명주기에 영향을 미치지 않습니다.weak_ptr.lock()
을 사용하여shared_ptr
로 변환해야만 객체를 안전하게 접근할 수 있습니다.shared_ptr
이 삭제된 후weak_ptr.lock()
을 호출하면nullptr
이 반환됩니다.expired()
를 사용하여 객체가 삭제되었는지 확인할 수 있습니다.
-
어떤 특정 이벤트 이후 스마트 포인터의 리소스를 즉시 해제하고 싶다면
reset()
을 사용할 수 있습니다. -
cpp
std::unique_ptr<int> up = std::make_unique<int>(100); up.reset(); // 리소스 즉시 해제
-
여러
shared_ptr
이 같은 객체를 공유할 때, 일부shared_ptr
만 명시적으로 해제할 수 있습니다. -
cpp
auto sp1 = std::make_shared<int>(10); auto sp2 = sp1; // 참조 카운트: 2 sp1.reset(); // sp1만 해제, 객체는 유지됨
-
weak_ptr
을 캐싱에 활용하고 필요할 때만 객체를 생성하도록 할 수 있습니다. -
cpp
std::shared_ptr<int> sp = std::make_shared<int>(50); std::weak_ptr<int> cache = sp; // 캐싱 sp.reset(); // 객체 삭제 if (cache.expired()) { std::cout << "Cache expired, reload required!" << std::endl; }
std::unique_ptr::reset()
: 객체를 즉시 삭제하고nullptr
로 설정합니다.std::shared_ptr::reset()
: 참조 카운트를 감소시키고, 마지막shared_ptr
이 삭제될 때 객체를 해제합니다.std::weak_ptr::reset()
:shared_ptr
의 객체와의 연결을 해제하지만, 객체 소멸에는 영향을 주지 않습니다.
- 스마트 포인터를 사용할 때
reset()
을 적절히 활용하면 메모리를 효과적으로 관리할 수 있습니다. - 하지만, 과도한
reset()
사용은 불필요한 리소스 해제를 초래할 수 있으므로 주의해야 합니다.
- 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄
728x90
반응형
'C C++' 카테고리의 다른 글
C++23 std::observer_ptr: 소유권 없는 안전한 포인터 래퍼(pointer wrapper) (0) | 2025.03.20 |
---|---|
생 포인터(raw pointer) std::raw_pointer — 표준 C++에 존재할까? (0) | 2025.03.20 |
C++17에서 std::auto_ptr가 제거된 이유 (0) | 2025.03.20 |
std::unique_ptr 멀티스레드 환경 사용 시 주의사항 (0) | 2025.03.19 |
C++11 std::move 개념과 활용 — 이동 시멘틱의 올바른 이해 (0) | 2025.03.19 |