Re: Challenging GotW 66's moral



Thanks for your great reply, Norbert!


I think in my case, I should use local try block other than function try
block, right?


regards,
George

"Norbert Unterberg" wrote:

George schrieb:

In GotW #66, one of the moral is the exception handler of constructor should
not do any like resource free task. I do not agree. Here is the quoated moral
and my code to prove this moral will have memory leak.

Anything wrong with my analysis?

Yes. There is something wrong. See below.

http://www.gotw.ca/gotw/066.htm

Moral #1: Constructor function-try-block handlers have only one purpose --
to translate an exception. (And maybe to do logging or some other side
effects.) They are not useful for any other purpose.


[Code]
class A
{
private:

int* p;

public:

A()
try
{
p = new int[10];
******
Constructor function-try-block handlers would be used to enable exception
handling for exceptions thrown *outside* of your own constructor. They would
catch excpetions thrown by base and member constructors.

The example you show here does not justify the use of a function-try-block. You
would use a normal try-block here:

A()
{
try
{
p = new int[10];
}
catch (std::bad_alloc&)
{
// p was not allocated
}
}

******

// there are some other exceptions here

}
catch (bad_alloc)
{
// do not delete since bad_alloc means memory pointed by p is not
allocated
*****
How do you know? std:bad_alloc could have been thrown by the code you did not
show ("there are some other exceptions here"). And then p would have been
allocated but not freed.
*****
}
catch (...)
{
// if we do not delete p, there will be memory leak
// at this point, we are conflicting with Gotw 66's moral 1
if (p) delete[] p;
******
You can not access p here. Remeber:

"Referring to any non-static member or base class of an object in the handler
for a function-try-block of a constructor or destructor for that object results
in undefined behavior."

Accessing p here results in undefined behaviour. The instance of A never
existed, so even if your compiler does not complain the result is still undefined.

BTW why if (p)?
1. It is perfectly fine to use delete on the null-pointer
2. p can never be 0 here anyway, so why bother?
******
}
}
[/Code]

You forget the most important Moral #7: Using RAII resolves all these problems
and issues, and maybe more than you might think of now.

Norbert

.



Relevant Pages