3. shared_ptr 제어블록, 순환 참조, weak_ptr
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C++
// ============================================================================
// [언어 내부동작 문제] C++ - shared_ptr 제어블록, 순환 참조, weak_ptr
// ----------------------------------------------------------------------------
// 주제:
// std::shared_ptr 의 제어블록(control block)과 (원자적) 참조계수, weak_ptr 가
// 강한 계수를 올리지 않는다는 점, enable_shared_from_this, 그리고 서로를 shared_ptr
// 로 가리키는 순환 참조가 일으키는 누수.
//
// 과제:
// 1) 아래 프로그램의 출력을 예측하라. 특히 각 use_count 값과, 끝에서 어떤 객체의
// 소멸자(dtor)가 호출되고 어떤 것이 "호출되지 않는지"를 정확히 적어라.
// 2) weak_ptr 가 use_count 에 어떤 영향을 주는지, shared_from_this 가 use_count 를
// 어떻게 바꾸는지 설명하라.
// 3) 끝에서 회수되지 못하는(소멸자가 불리지 않는) 객체가 있다면 무엇이고, 그 이유를
// 제어블록/참조계수 관점에서 설명한 뒤, 이를 weak_ptr 로 어떻게 고치는지 제시하라.
// (먼저 직접 예측·설명을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
#include <iostream>
#include <memory>
#include <string>
#include <utility>
struct Node : std::enable_shared_from_this<Node>
{
std::string name;
std::shared_ptr<Node> next; // 강한 참조
Node(std::string n) : name(std::move(n)) { std::cout << "ctor " << name << "\n"; }
~Node() { std::cout << "dtor " << name << "\n"; }
};
int main()
{
auto a = std::make_shared<Node>("A");
std::cout << "a.use_count=" << a.use_count() << "\n";
std::weak_ptr<Node> w = a;
std::cout << "after weak, a.use_count=" << a.use_count() << "\n";
{
std::shared_ptr<Node> b = a;
std::cout << "in block, a.use_count=" << a.use_count() << "\n";
}
std::cout << "after block, a.use_count=" << a.use_count() << "\n";
auto x = std::make_shared<Node>("X");
auto y = std::make_shared<Node>("Y");
x->next = y;
y->next = x;
std::cout << "x.use_count=" << x.use_count()
<< ", y.use_count=" << y.use_count() << "\n";
auto self = x->shared_from_this();
std::cout << "x.use_count after shared_from_this=" << x.use_count() << "\n";
self.reset();
std::cout << "end of main\n";
return 0;
} 내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.