반응형
C++ 17부터 std::shared_ptr가 [] 연산자를 지원한다. 따라서 ssptr[i]와 같은 연산을 지원한다.
이 의미는 (ssptr.get())[i]와 같은 의미이다. 즉 int* p = new int[5]에서 p[i]와 동일하다.
그러려면 std::shared_ptr<int[]> ssptr(new int[5], deleter) 와같이 선언한다. 소유하려는 타입이 array일 경우 deleter를 지정하지 않아도 default_deleter가 자동으로 설정된다. deleter는 나중에 소유한 array의 메모리를 해제해준다.
deleter를 직접 작성할 순 있지만 형태는 정해져 있는 듯 하다.
template <typename T>
struct array_deleter
{
void operator()(T const* p)
{
delete[] p;
}
};
위와 같이 선언했을 경우 std::shared_ptr<int[]> ssptr(new int[5], array_deleter<int>()); 와 같이 선언한다.
나는 포인터를 저장하는 배열이 필요해서 시도해봤더니 잘 되는 것 같다. 이 경우 배열의 크기만큼 delete를 해주어야 해서 size가 필요한데, deleter에 추가로 인자를 전달하지 못하는 것 같다. 그래서 현재 내 방법엔 미리 크기를 알고 있는 경우만 해당된다.
내가 하려는 것을 로우 포인터 타입으로 보면 다음과 같다.
// 포인터를 저장하는 배열 생성
int** pArray = new int* [5];
for(size_t i = 0; i < 5; ++i)
{
pArray[i] = new int(i);
}
...
// 메모리 해제
for(size_t i = 0; i < 5; ++i)
{
delete pArray[i];
}
delete[] pArray;
위와 같은 동작을 shared_ptr로 하려면 다음과 같이 한다.
template <typename T>
struct array_deleter
{
void operator()(T const* p)
{
for (size_t i = 0; i < 5; ++i)
{
delete p[i];
}
delete[] p;
}
};
std::shared_ptr<int*[]> sptr(new int* [5], array_deleter<int*>());
// 0 1 2 3 4
for(size_t i = 0; i < 5; ++i)
{
sptr[i] = new int(i);
cout << *sptr[i] << " ";
}
sptr이 자신의 스코프를 벗어나면 deleter가 호출되며 배열의 각 요소에 저장된 포인터를 해제하고 마지막으로 배열 메모리까지 정상적으로 해제한다.
'C,C++ > C++' 카테고리의 다른 글
Unity Build(유니티 빌드)란? (0) | 2021.11.14 |
---|---|
2D vector size를 통해 초기화 하는 법 (0) | 2021.09.09 |
[C++ 17] 템플릿 특수화보다 사용하기 좋은 if constexpr (0) | 2021.01.01 |
[C++] placement new - 내가 원하는 메모리에 객체를 할당하고 싶다면 (0) | 2020.12.25 |
클래스에서 가변 인자 템플릿 이용 시 함수 선언 방법 (0) | 2020.12.02 |
댓글