In C++ FAQ, the [16.16] gives the following example,
void manipulateArray(unsigned nrows, unsigned ncols[])
{
typedef Fred* FredPtr;
FredPtr* matrix = new FredPtr[nrows];
// Set each element to NULL in case there is an exception later.
// (See comments at the top of the try block for rationale.)
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = NULL;
try {
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = new Fred[ ncols[i] ];
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols[i]; ++j) {
someFunction( matrix[i][j] );
}
}
if (today == "Tuesday" && moon.isFull()) {
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
return;
}
...code that fiddles with the matrix...
}
catch (...) {
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
throw; // Re-throw the current exception
}
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
}
Why we have to use delete this way, I mean,
First delete[] matrix[i-1];
then delete[] matrix;
Moreover, what’s the point of after the whole “try…catch” cycle, we still have to put
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
at the end of this function.
The
try/catchblock is necessary to ensure proper clean-up even if an exception is thrown anywhere in the code before the normal clean-up happens. This includes an exception in one of thenewexpressions. Thedelete[]is safe because all the relevant pointers were initially set to zero, so that the deletion is valid even if no allocation ever occurred.(Note that if any exception does occur, it will still be propagated outside the function. The local
try/catchblock only ensures that the function itself doesn’t leak any memory.)There are two sets of arrays: one is the outer array
matrix, which is an array of pointers. This array gets allocated first and deleted last. Second, each elementmatrix[i]is itself a pointer to an array ofFredelements. Each array gets allocated in the firstforloop, and thus has to be deleted in another loop at the end.