본문 바로가기

Programming/C&CPP

shared_ptr에서 배열(array) delete[]로 해제하는 방법

반응형

shared_ptr은 C++에서 제공하는 스마트 포인터입니다.

메모리의 관리가 까다로운 C++에서 유용하게 사용이 가능합니다.

shared_ptr은 참조 카운트(Reference Count)를 통해서 메모리 해제 시점을 결정합니다.

shared_ptr은 기본적으로 사용된 메모리를 delete로 해제하게 됩니다.

배열(new [])이 저장되어 있을 경우에 배열의 해제를 할 수 있는 방법은 다음과 같습니다.

1. delete[]를 호출하는 함수 객체를 생성

초기화를 할 때 포인터와 함께 메모리를 해제할 때 사용할 함수를 전달하는 방법입니다.

shared_ptr은 생성자에 메모리 해제를 위한 deleter를 전달할 수 있습니다.

메모리 할당을 위한 함수를 전달하는 것도 가능합니다.

함수 객체 혹은 함수를 전달해서 shared_ptr이 소멸될 때 지정된 메모리 해제 방법을 실행하게 합니다.

다음과 같은 형태로 작성하면 됩니다.

#include <memory>

template <typename T>
struct Array_Deleter
{
	void operator()(T* p)
	{
		delete[] p;
	}
};

int main()
{
	std::shared_ptr<int> ptr(new int[10], Array_Deleter<int>());

	// Do something
	// Release by Array_Deleter functor

	return 0;
}

Array_Deleter라는 클래스(액세스 지정때문에 struct를 사용)를 만들고 delete[]를 호출하게 합니다.

shared_ptr을 생성할 때 할당된 메모리와 Array_Deleter<int>()를 전달합니다.

<int> 안의 타입은 실제 할당된 메모리의 타입과 동일하게 하면 됩니다.

작업이 완료되면 자동으로 메모리 해제가 실행되면서 정상적으로 메모리 배열이 해제됩니다.

2. std::default_delete 사용

C++의 STL에는 이미 delete와 delete[]를 기본으로 지정할 수 있게 해놓았습니다.

위의 방법보다 좀 더 간단하게 다음과 같이 구현할 수 있습니다.

#include <memory>

int main()
{
	std::shared_ptr<int> ptr(new int[10], std::default_delete<int[]>());

	// Do something
	// Release by Array_Deleter functor

	return 0;
}

default_delete에 타입만 지정하면 쉽게 사용이 가능합니다.

다만 별도의 해제 방법(free(), CoTaskMemFree() 등)을 사용할 때는 위의 방법을 사용해야 합니다.

3. C++11에 추가된 lambda를 활용

C++11에 추가된 lambda를 활용해서 메모리를 할당하는 곳에 deleter 구현을 함께 두는 방법입니다.

다음과 같이 구현이 가능합니다.

#include <memory>

int main()
{
	std::shared_ptr<int> ptr(new int[10], [](int* p)
	{
		delete[] p;
	});

	// Do something
	// Release by Array_Deleter functor

	return 0;
}

메모리를 할당하는 곳에 해제를 위한 deleter 구현이 함께 있기 때문에 쉽게 확인이 가능합니다.

위의 방법으로 배열로 할당된 메모리를 해제할 수 있습니다.

반응형