한 주 정도 포스팅이 밀린 것 같다.
다시 얼른 정리해야지
뭐든지 한 번 밀리면 계속 밀리는 것 같다. 게으름에도 관성이 있다. 하루가 이틀이 되고 이틀이 일주일이 된다.
어쨋든, 메모리 관리 관련해서 다시 이어서 써보자.
0. 서론
이전 포스팅에서는 컴퓨터의 메모리가 무엇인지? C/C++ 동네에서는 어떻게 메모리에 접근하며 메모리를 사용하는지에 대해 정리하였다.
이번에는 스마트 포인터라는 C++로 넘어오면서 추가된 개념을 정리해보려고 한다. 이름 그대로 똑똑한 포인터이다.
왜 스마트 포인터가 등장했을까?
포인터는 앞서 다뤘듯이 메모리에 접근할 수 있는 주소값을 담고있는 변수이다.
그리고 우리는 이 변수를 예민하게 다뤄야한다. 메모리를 할당받으면 다시 메모리르 해제해줘야하는 꽤나 귀찮은 작업들을 매번 해줘야한다.
만약에 해제하지않는다면, 잘못된 메모리에 접근하거나 최악의 경우 프로그램이 죽는 이슈까지 발생한다.
(쓰면서 갑자기 궁금한 점은 프로그램은 왜,굳이, 죽기까지 할까? 이거는 나중에 알아보기로 하자.)
이런 귀찮고 예민한 작업을 C++에서는 스마트포인터에게 넘김으로써 안정적인 개발이 가능하다.
만약 본인이 쌩 포인터 변수를 잘 관리할 자신이 있다면 굳이 안써도 된다.
그러면 똑똑한 포인터, 스마트 포인터의 종류부터 알아보자.
1. 스마트 포인터의 종류
- std::unique_ptr
- std::shared_ptr
- std::weak_ptr
이렇게 3가지 종류가 있으며 오늘은 위의 2가지 std::unique_ptr, std::shared_ptr 만 알아보도록 하자.
2. std::unique_ptr
std::unique_ptr는 포인터 변수를 독점적으로 소유하고 있는 포인터이다.
따라서 한 번 포인터 변수를 선점하게 되면 std::unique_ptr가 포인터를 관리하게 된다.
여기서 관리한다는게 뭘까?
예를 들어, 아래와 같이 std::unique_ptr를 사용했다고 치자.
std::unique_ptr<A> ptr(new A);
A 라는 객체의 인스턴스가 ptr변수 스마트 포인터에게 소유권이 전달되고 관리된다.
std::unique_ptr의 내부구현은 class 처럼 생성자 & 소멸자가 존재하며
std::unique_ptr가 파괴되는 시점에 소멸자에서 A 인스턴스의 메모리도 정리를 하며 파괴된다.
따라서, 개발자가 직접 A 의 메모리 정리 필요없이 std::unique_ptr가 알아서 정리를 하게된다.
그러면 관리의 개념을 얼추 알았는데
#독점 #소유 한다는건 무슨 의미일까 ?
예를 들어, A 객체에 print( ) 라는 함수가 있다고 가정해보자.
소유권을 받은 ptr 변수는 print( ) 라는 함수가 호출이 가능할 것이다.
만약에 아래와 같은 상황이 발생한다면?
std::unique_ptr<A> ptr2 = ptr
ptr2 도 같은 A 인스턴스를 소유하게 될것이며 std::unique_ptr의 정체성을 잃게 될것이다.
std::unique_ptr은 독점이다! 다른 스마트포인터가 본인이 소유한 자원을 품을 수 없게 해야한다.
그래서 위와 같은 상황은 컴파일러 오류가 발생한다.
std::unique_ptr 내부는 복사생성자가 삭제되어있다. 그럼으로 다른 스마트 포인터로 소유권 복사가 되지 않는다.
그럼에도 소유권을 넘기고 싶을땐 어찌해야할까?
C++ 에는 이동(move) 라는 개념이 있다. std::unique_ptr는 이동생성자를 통해서 소유권 이전이 가능하다.
(이동, 우측값에 대해서는 다음에 알아보자.)
std::unique_ptr<A> ptr2 = std::move(ptr)
위와 같이 move를 통해서 ptr2로 소유권이 넘어가며 변수 ptr은 초기상태로 돌아가 아무것도 소유하지 않은 상태가 된다.
어후.. 쓰다보니 좀 길어지니깐 2부로..
그럼 20000..
'CS > C++' 카테고리의 다른 글
메모리 관리(2) - 포인터의 사용법과 사용이유 (0) | 2023.02.15 |
---|---|
메모리 관리(1) - 포인터(pointer) (0) | 2023.02.13 |