We are committed to provide service 24 X 7

Deals, Shopping, Training, Tools

C++11 Smart Pointer – Part 2: shared_ptr and Custom Deletor

In this article we will discuss how to use custom deleter with std::shared_ptr.


When a shared_ptr object goes out of scope, its destructor is called. Inside its destructor it decrements the reference count by 1 and if new value of reference count is 0 then it deletes the associated raw pointer.

Advertisements

To delete the internal raw pointer in destructor, by default shared_ptr calls the delete() function i.e.

delete Pointer;

But its not always that we want to use delete function in destruction, there can be other requirements too like,

If shared_ptr object points to an array instead of a simple pointer,

std::shared_ptr<int> p3(new int[12]);

In its destructor shared_ptr will try to delete the int array i.e. int [] by calling

delete

function, whereas as correct way is using

 delete []

Adding custom deleter to shared_ptr<>

In such case we can pass a callback to shared_ptr’s constructor, that will be called from its destructor for deletion i.e.

Custom Deleter as function Pointer

// function that calls the delete [] on received pointer
void deleter(Sample * x)
{
	std::cout << "DELETER FUNCTION CALLEDn";
	delete[] x;
}

Pass the function pointer in constructor of shared_ptr to provide custom deleter i.e.

// Creating a shared+ptr with custom deleter
std::shared_ptr<Sample> p3(new Sample[12], deleter);

Check complete example as follows,

#include <iostream>
#include <memory>

struct Sample
{
	Sample()
	{
		std::cout << "CONSTRUCTORn";
	}
	~Sample()
	{
		std::cout << "DESTRUCTORn";
	}
};

// function that calls the delete [] on received pointer
void deleter(Sample * x)
{
	std::cout << "DELETER FUNCTION CALLEDn";
	delete[] x;
}

int main()
{
	// Creating a shared+ptr with custom deleter
	std::shared_ptr<Sample> p3(new Sample[12], deleter);
	return 0;
}

Ouput:

CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
DELETER FUNCTION CALLED
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR

Custom Deleter as Lambda Function or Function Object

We can also attach Function objects and Lambda functions as callback i.e.,

class Deleter
{
	public:
	void operator() (Sample * x) {
		std::cout<<"DELETER FUNCTION CALLEDn";
		delete[] x;
	}
};

// Function Object as deleter
std::shared_ptr<Sample> p3(new Sample[12], Deleter());

// Lambda function as deleter
std::shared_ptr<Sample> p4(new Sample[12], [](Sample * x){
	std::cout<<"DELETER FUNCTION CALLEDn";
		delete[] x;
});

There might be other cases when we don’t need to delete any memory we just need to releasing memory or resources to a pool etc.

Check out an example with dummy implementation of Memory Pool and Custom Deletor.

#include <iostream>
#include <memory>

struct Sample
{
};

// Memory Pool Dummy Kind of Implementation
template<typename T>
class MemoryPool
{
public:
	T * AquireMemory()
	{
		std::cout << "AQUIRING MEMORYn";
		return (new T());
	}
	void ReleaseMemory(T * ptr)
	{
		std::cout << "RELEASE MEMORYn";
		delete ptr;
	}
};
int main()
{
	std::shared_ptr<MemoryPool<Sample> > memoryPoolPtr = std::make_shared<
			MemoryPool<Sample> >();

	std::shared_ptr<Sample> p3(memoryPoolPtr->AquireMemory(),
			std::bind(&MemoryPool<Sample>::ReleaseMemory, memoryPoolPtr,
					std::placeholders::_1));
	return 0;
}

Output:

AQUIRING MEMORY
RELEASE MEMORY

 

Cart

Your Cart is Empty

Back To Shop