Do I always have to use try ... finally to clean up in case of exceptions ?

This is a discussion on Do I always have to use try ... finally to clean up in case of exceptions ? within the Delphi forums in Programming Languages category; Hello I would like to use exceptions in my program to spare me all the checkes for the return code from various functions each time I call them. And also to make bugs like Access Violation look like they are handled and not crash my app. The problem is exceptions handlers are at many stack frames (nested called functions) away from the raise point, and in case of an exception all the called functions would return without destroing and freeing class instances created. I think this would cause memory and resource leaks. Do I have to begin each of my ...

Go Back   Application Development Forum > Programming Languages > Delphi

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-07-2008, 08:34 AM
Timothy Madden
Guest
 
Default Do I always have to use try ... finally to clean up in case of exceptions ?

Hello

I would like to use exceptions in my program to spare me all the checkes for the
return code from various functions each time I call them. And also to make bugs
like Access Violation look like they are handled and not crash my app.

The problem is exceptions handlers are at many stack frames (nested called functions)
away from the raise point, and in case of an exception all the called functions would
return without destroing and freeing class instances created.

I think this would cause memory and resource leaks.

Do I have to begin each of my functions and procedures with try ... finally to be able
to work with exceptions in my program ? Do I need a nested try ... finally for every
class instance I create to be sure it is destroyed ?

Is there a way to have the destructors always called by the language, like when the
constructor raises the exception ?

I know, I am used with other environments, but I would like to know how things are in
Delphi.

Thank you,
Timothy Madden
Reply With Quote
  #2  
Old 08-07-2008, 09:09 AM
Wayne Niddery \(TeamB\)
Guest
 
Default Re: Do I always have to use try ... finally to clean up in case of exceptions ?

"Timothy Madden" <terminatorul@gmail.com> wrote in message
news:Lucy121811247464650x9c256ec@jupiter.eamobile. ad.ea.com...
>
> Do I have to begin each of my functions and procedures with try ...
> finally to be able
> to work with exceptions in my program ? Do I need a nested try ... finally
> for every
> class instance I create to be sure it is destroyed ?


If there is a chance it can exit that procedure before otherwise reaching
the code that frees these instances (whether by exception or by deliberate
choice) then yes - that is exactly what try/finally is for.

In general, the use of try/except should be rare, use of try/finally
generous.

> Is there a way to have the destructors always called by the language, like
> when the
> constructor raises the exception ?


No. Not unless you want to get into defining every class as a descendant of
TInterfacedObject so that it has interface reference counting, but then you
must also create and use instances of the *interface*, not the class - IOW
you will need to make more tedious changes throughout your code than it will
be to add try/finally blocks.

--
Wayne Niddery - TeamB (www.teamb.com)
Winwright, Inc. (www.winwright.ca)

Reply With Quote
  #3  
Old 08-07-2008, 09:59 AM
Caleb Hattingh
Guest
 
Default Re: Do I always have to use try ... finally to clean up in case ofexceptions ?

> Do I have to begin each of my functions and procedures with try ...
> finally to be able
> to work with exceptions in my program ? Do I need a nested try ...
> finally for every
> class instance I create to be sure it is destroyed ?


As an aside, there is an additional use for try-finally:

while not DataSet.Eof do
begin
try
<code>
if condition then
Continue; {Continue with next record}
<code>
<code>
<code>
finally
DataSet.Next; {Make sure the next record is really selected}
end;
end;

Regarding exceptions, it is difficult to perfectly manage exceptions
without resulting in needing to bring the app down. try-finally with
exceptions are most useful when you know that an outer scope is going to
handle exceptions with try-except; then you know that there are some
conditions where the app is not going to come down due to an exception,
and so you must make sure that any locally allocated memory is freed
before moving into the exception handler. But it is difficult to be
rigourous about this in practice.
Reply With Quote
  #4  
Old 08-07-2008, 10:55 AM
Jens Gruschel
Guest
 
Default Re: Do I always have to use try ... finally to clean up in case ofexceptions ?

> Do I have to begin each of my functions and procedures with try ... finally to be able
> to work with exceptions in my program ?


No. As a simple rule put all code that has to be run to clean up in a
finally section. Like

Screen.Cursor := crHourClass;
try
LengthyOperation;
finally
Screen.Cursor := crDefault;
end;

or

MyObject := TMyObject.Create;
try
MyObject.DoSomething;
finally
MyObject.Free;
end;

In both examples the first line is not inside the try block, simply
because there is nothing to clean up in case it fails (if the mouse
cursor never changes to an hourglass there is no need to restore it
later). Just in case you wonder what's going on after a constructor like
TMyObject.Create was execute successfully, but before the object was
assigned to the MyObject variable: Some operations don't have to be
protected by try/finally, simply because no exception can be raised there.

> Is there a way to have the destructors always called by the language,

like when the
> constructor raises the exception ?


Whenever an exception is raised within a constructor the destructor is
called automatically. Afterwards exception handling continues normally
and except and finally-blocks are executed. That's why a constructor
call should not be made within the try-block, otherwise you'd destroy
the object twice. Before a constructor is executed all fields are
initialized with 0 / nil, that's why constructors partially executed
usually don't confuse the destructor (it simply doesn't clean up fields
which haven't been initialized yet).

> Do I need a nested try ... finally for every
> class instance I create to be sure it is destroyed ?


For every class instance used locally inside of a function, yes. If you
create and destroy more than one object at once there is an alternative
to having two nested try/finally blocks:

MyObject1 := TMyObject.Create;
try
MyObject2 := TMyObject.Create;
try
MyObject1.DoSomethingWith(MyObject1);
finally
MyObject2.Free;
end;
finally
MyObject1.Free;
end;

or

MyObject1 := nil;
MyObject2 := nil;
try
MyObject1 := TMyObject.Create;
MyObject2 := TMyObject.Create;
MyObject1.DoSomethingWith(MyObject1);
finally
MyObject2.Free;
MyObject1.Free;
end;

The latter works, because in case if any constructor fails or if the
code afterwards fail, each object variable is either nil or valid. And
since Free works with nil objects (and simply does nothing) that's
alright, the object is not destroyed twice.

> I know, I am used with other environments, but I would like to know how things are in
> Delphi.


One final thing: Raising a new exception in an except-block is alright,
but never raise a new exception in a finally block! And since
destructors are frequently called within finally-blocks, never raise an
exception in a destructor! Clean-up code should always work without
exceptions.

--
Jens Gruschel
http://www.pegtop.net
Reply With Quote
  #5  
Old 08-07-2008, 11:00 AM
Jens Gruschel
Guest
 
Default Re: Do I always have to use try ... finally to clean up in case ofexceptions ?

> Is there a way to have the destructors always called by the language, like when the
> constructor raises the exception ?


Sorry, I misread your question, but Wayne already answered it.

--
Jens Gruschel
http://www.pegtop.net
Reply With Quote
  #6  
Old 08-07-2008, 12:48 PM
Remy Lebeau \(TeamB\)
Guest
 
Default Re: Do I always have to use try ... finally to clean up in case of exceptions ?


"Timothy Madden" <terminatorul@gmail.com> wrote in message
news:Lucy121811247464650x9c256ec@jupiter.eamobile. ad.ea.com...

> The problem is exceptions handlers are at many stack frames (nested
> called functions) away from the raise point, and in case of an exception
> all the called functions would return without destroing and freeing class
> instances created.
>
> I think this would cause memory and resource leaks.


Yes, it would.

> Do I have to begin each of my functions and procedures with try ...
> finally
> to be able to work with exceptions in my program ?


Not strictly like that, no. Just protect the individual objects you are
using along the way, ie:

procedure Test;
var
obj: TSomeClass;
begin
do some things...
...
obj := TSomeClass.Create;
try
use obj as needed...
finally
obj.Free;
end;
...
do some more things...
end;

> Do I need a nested try ... finally for every class instance I create
> to be sure it is destroyed ?


Yes.

> Is there a way to have the destructors always called by the language,
> like when the constructor raises the exception ?


No.


Gambit


Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 08:15 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.