기본적인 포인터
#include <iostream>
int main()
{
int *rawPtr = new int(10);
std::cout << *rawPtr << std::endl;
delete rawPtr;
}
기본 포인터는 동적으로 메모리를 할당해주고
delete로 반드시 메모리 해제를 해줘야 함
보통 new / delete를 세트로 잘해주겠지만
프로젝트를 진행하다 보면 동적 할당하는 곳과 delete 하는 곳이 달라져
문제가 발생하는 경우가 생김
스마트 포인터는 3가지 종류가 있음
- shared_ptr
- unique_ptr
- weak_ptr
shared_ptr
shared_ptr는 내부에 레퍼런스 카운트가 존재하고
레퍼런스 카운트가 0이 될 때 메모리에서 해제됨
위 코드를 보면 sharedPtr을 2, 3이 추가로 참조하고 있음
이러면 본인을 포함해 총 3의 레퍼런스 카운트를 가지게 됨
#include "pch.h"
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> sharedPtr = std::shared_ptr<int>(new int(10));
std::cout << *sharedPtr << " " << sharedPtr.use_count() << std::endl;
std::shared_ptr<int> sharedPtr2 = sharedPtr;
std::cout << *sharedPtr2 << " " << sharedPtr.use_count() << " " << sharedPtr2.use_count() << std::endl;
std::shared_ptr<int> sharedPtr3 = sharedPtr;
std::cout << *sharedPtr3 << " " << sharedPtr.use_count() << " " << sharedPtr2.use_count() << " " << sharedPtr3.use_count() << std::endl;
}
결과
sharedPtr, 2, 3이 모두 같은 레퍼런스 카운트를 공유함
shared_ptr을 쓰다 보면 순환 참조 문제가 발생할 수 있음
unique_ptr
unique_ptr는 유일하게 존재해야 할 포인터를 위함
unique_ptr의 생성자를 확인하면 복사 생성자와 대입 연산자가 삭제돼있음
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
unique_ptr는 std::move를 이용해 소유권을 넘겨야 함
#include "pch.h"
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> uniquePtr = std::unique_ptr<int>(new int(10));
std::unique_ptr<int> uniquePtr2 = std::move(uniquePtr);
std::cout << *uniquePtr2 << std::endl;
std::cout << *uniquePtr << std::endl; // 에러 발생
}
결과
소유권이 넘어가 uniquePtr은 empty가 됨
uniquePtr에 접근하면 에러가 발생함
weak_ptr
weak_ptr는 레퍼런스 카운트를 올리지 않음
#include "pch.h"
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> sharedPtr = std::shared_ptr<int>(new int(10));
std::shared_ptr<int> sharedPtr2 = sharedPtr;
std::cout << *sharedPtr << " " << sharedPtr.use_count() << std::endl;
std::weak_ptr<int> weakPtr = sharedPtr;
std::cout << *weakPtr.lock() << " " << weakPtr.use_count() << std::endl;
}
weakPtr은 lock함수로 참조하고 있는 포인터를 가져옴
lock함수는 shared_ptr을 리턴하고 사용하는 동안 레퍼런스 카운트가 1 오름
'개발 > C++' 카테고리의 다른 글
C++ shared_ptr 사용할 때 주의할 점 (0) | 2019.05.24 |
---|---|
컴파일러 최적화 (0) | 2019.05.13 |
C++ Map, HashMap(unorder_map) 사용할 때 주의할 점 (0) | 2019.04.27 |
C++ 가상 소멸자 (feat. 상속 생성자 소멸자 호출순서) (0) | 2019.04.22 |
C++ 소켓 에코 채팅 구현하기 (0) | 2019.04.15 |