본문 바로가기
C++

스마트 포인터, 강참조와 약참조

by PainDiver 2022. 11. 26.

 

 

이것도 면접에서 나온 질문

스마트 포인터가 뭔지 아냐는 질문이었다.

 

당연히 알지, 맨날 쓰니까..

쉐어드 포인터, 유니크포인터, 윅포인터 종류가 있고, 메모리 할당을 한 후에 사용자가 신경을 쓰지않아도, 프로그램 종료 시 메모리 할당이 자동으로 해제되는 포인터라고 설명을 했다.

 

쉐어드 포인터는 어떻게 동작하냐고 물어보셨는데,

쉐어드 포인터는 내부적으로 레퍼런스 카운팅을 하여 할당된 메모리가 다른 곳에서 사용될 때 카운팅이 하나씩 오르고, 레퍼런스 카운트가 0이 될 시에 메모리할당이 해제되는 방식으로 이해하고 있다고 말을했고, 서로 얽혀있는 순환참조가 발생하지 않는 이상 메모리 할당이 자동적으로 해제될 수 있다고 답했다.

 

그리고 면접관님이 말씀하신게, 순환참조는 어떤식으로 일어나냐고 물어보셨다.

A B 클래스가 서로의 쉐어드 포인터를 들고 있다면, 레퍼런스 카운팅이 0으로 내려가지 않아 메모리 해제가 되지 않고 누수가 발생할 수 있다고 답했다.

 

그렇다면 순환참조를 어떤식으로 해결할 수 있냐고 물으셨는데,

이 때는 둘 중 한 클래스가 쉐어드 포인터가 아닌 윅 포인터를 들고있으면 된다고 답을 했다.

 

그리고 훅 들어오는 질문 "그렇다면 강참조와 약참조를 아시나요?'

하.. 이거 본거 같은데, 진짜 생각이 하나도 안났다.. 그래서 모른다 했다 ㅠㅠ..

 

그렇다면 윅포인터가 어떻게 동작하는지 알고계시나요?라고 물어보셨는데.

모른다.. 그래..  알면 약참조 강참조에서 대답했겠지.

그래서 그냥 생각나는대로 말했다. 약참조는 레퍼런스 카운트를 세지 않는다..

왜냐? 윅포인터가 쉐어드 포인터의 생명주기에 영향을 끼치면 안되는거는 알고있으니까! 

반만 맞은것 같다.

 

면접끝나고 찾아보니까 전에 봤던 내용이라 너무 허무했다..

 

잡설은 각설하고 약참조와 강참조를 알아보자.

 

쉐어드 포인터와 윅 포인터는 어떻게 순환참조를 해결할 수 있는걸까?

 

잘 생각해보면, 순환 참조는 서로를 참조하기 때문에 레퍼런스 카운트가 0으로 내려가지 않아서 메모리 할당이 해제되지 않는 거다, 그렇다면 윅포인터는 분명 쉐어드 포인터의 레퍼런스 카운트를 건들지 말아야 한다. 여기까지는 맞았다

 

그런데 윅포인터도 이 친구만의 레퍼런스 카운트를 세고있다. 그것이 약참조, 그리고 강참조는 쉐어드포인터가 사용하는 레퍼런스 카운트다.

 

이 윅포인터는 쉐어드 포인터를 이용해서만 사용 가능하다.

그러다보니까, 이 윅포인터가 가리키는 원시 포인터는 쉐어드 포인터의 레퍼런스 카운트(강참조)의 개수에 의해서 생명이 유지되는 것이고, 이 강참조가 0이 되는 순간 소멸된다는 것이다.

 

윅포인터의 경우, 이 이유로 인해서 사용할 때 원시포인터의 생사여부를 모르는 채로 사용하는데, nullptr를 참조하는것을 방지하기 위해서 expired라는 함수를 통해서 원시포인터의 생사여부를 확인가능하다.

 

 

[Reference]

auto_ptr, unique_ptr, shared_ptr and weak_ptr - GeeksforGeeks