• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

shared_ptr에서 순환참조가 이해가 잘 안가서 질문드립니다.

21.08.30 17:09 작성 조회수 444

0

예를들어 

shared_ptr<Player> A = std::make_shared<Player>();

shared_ptr<Player> B = std::make_shared<Player>();

A = B;

B = A;

이렇게 있다고 하면 메모리 상황은

A B 변수둘다 한 스코프에 있다고 했을때 변수 A에 대해서 스코프에 벗어나 스택에서 Pop이 일어날 경우에 변수 A가 heap영역에서 가리키고 있는 Player 객체는 위 그림에서 처럼 2개인데(현재 heap Player객체 2개의 대한 각각의 RefCount값은 2인상태) 가리키고 있는것 중 1개만 해제를 시킨다고 보는게 정확한건가요? 메모리릭이 발생하지 않으려면 해제를 한 변수당 2번을 해줘야 된다고 생각하고 있는데 A B 둘다 가리키고 있는것은 각각 2개인데 정작 스택에서 벗어날때에는 1개씩만 해제를 시켜주어서 메모리릭이 발생하는건가 긴가민가해서 질문드립니다.

답변 2

·

답변을 작성해보세요.

1

예제가 잘못 되었습니다.

shared_ptr<Player> A = std::make_shared<Player>();
shared_ptr<Player> B = std::make_shared<Player>();
A = B;

여기서 A 또한 B를 가리키게 되므로
원래 있던 A 플레이어는 소멸됩니다. (RefCount = 0 되어서)
뒤늦게 B = A 를 해봤자 이미 A는 B랑 동일한 객체를 가리키는 상태이므로
이 부분은 아무런 의미가 없습니다.

unique_ptr을 사용할 수 없는 이유는 단순한데,
정말 소유권을 1명만 들고 있을 수 있기 때문입니다.
간단한 예를 들어 현실적으로 게임을 만들 때 Monster 정보를
ObjectManager에서 들고 있을 수도, Player가 타겟으로 지정해서 들고 있을 수도,
기타 다양한 경로에서 들고 있을 수 있고,
심지어 어떤 함수를 호출하면서 인자로 Monster를 넘겨야 할 수도 있는데
이런 상황에서 unique_ptr은 공유해서 사용할 수 없기 때문에 한계가 명확합니다.

shared_ptr를 남발하면 정확한 소멸 시점이 어려운 것은 맞지만,
소멸 시점이 정확히 떨어져야 한다면 shared_ptr, weak_ptr을 혼용해서 사용하면 됩니다.
아직 shared_ptr 이해도가 부족하신 것 같은데
위 예제에서
Player 소멸자에 breakpoint를 잡아서 객체가 날라가는 시점을
유의깊게 보시기 바랍니다.
그리고 앞으로 이렇게 단순하게 같은 scope에서 A, B를 만들고 테스트하는건 절대 아니고
아주 복잡한 게임 로직이 실행되면서 A, B를 이리 저리 넘긴다고 상상해보시기 바랍니다.

 

0

essenger M님의 프로필

essenger M

질문자

2021.08.30

답변 감사합니다!