There is a well-known problem with exceptions in C++ constructors. Only objects that are constructed completely are deleted in C++. Usually, the developer is supposed to take special measures against the possible memory leaks. So let us look into what Symbian offers and what else can be done to solve the issue.
Suppose, there is a class:
class Container
{
public:
Container ()
thePart1 = new Part1();
thePart2 = new Part2();
};
~Container()
delete thePart1;
delete thePart2;
private:
Part1 *thePart1;
Part2 *thePart2;
}
If object c of the Container class is being created as a local object:
void test ()
Container c();
…
and the exception arises on c construction, then c’s destructor is not called.
The results are that Part 1 and/or Part 2 are not deleted, and a memory leak takes place.
Symbian proposes to push the pointer to the newly created object onto the special stack – the so-called clean-up stack. In case of an exception, the clean-up stack is unwinded, and every pointer on it is deleted. So we could redesign our constructor the following way (for Symbian):
Container::Container ()
CleanupStack::PushL(thePart1);
CleanupStack::Pop(thePart1);
Of course, it works and looks better than:
try{
catch (…)
But it could be made easier and more elegant by changing the pointers to smart pointers:
// nothing to do!!
auto_ptr<Part1> thePart1;
auto_ptr<Part2> thePart2;
Thus, we decrease the risk of memory leaks on exceptions. At the same time, we don’t have to release our resources in the constructor. It seems like we don’t need to use CleanupStack in Symbian at all – just develop an auto_ptr class instead:
template<class T>
class auto_ptr
auto_ptr (T *p = 0): ptr(p) {}
~auto_ptr() {delete ptr;}
T *ptr;
Remember Me