Board index » delphi » Re: Assigned and FreeAndNil

Re: Assigned and FreeAndNil


2006-10-27 01:46:04 AM
delphi2
Craig Stuntz [TeamB] writes:
Quote
You can call any method on any reference
As Jon points out, I should have said "any non-virtual method" here.
--
Craig Stuntz [TeamB] ?Vertex Systems Corp. ?Columbus, OH
Delphi/InterBase Weblog : blogs.teamb.com/craigstuntz
Useful articles about InterBase development:
blogs.teamb.com/craigstuntz/category/21.aspx
 
 

Re: Assigned and FreeAndNil

Bob Dawson writes:
Quote

Agreed--it's quite common to see FreeAndNil being called on a
procedure variable right before it goes out of scope. In general, it
seems to me that the more one follows good OO practice, the less
FreeAndNil matters.
Where it seems to get used most (that I have seen) is for form variables.
Assign the global variable, and then FreeAndNil it in that form's OnClose
event so that other code can tell whether the form exists or not. Get rid of
the global vars and that "need" goes away. <g>If I need to see if a form
already/still exists, it is no problem to search in Screen.Forms.
--
Wayne Niddery - Winwright, Inc (www.winwright.ca)
"Nurture your mind with great thoughts. To believe in the heroic makes
heroes." ?Benjamin Disraeli
 

Re: Assigned and FreeAndNil

Craig Stuntz [TeamB] schrieb:
Quote
Craig Stuntz [TeamB] writes:

>You can call any method on any reference

As Jon points out, I should have said "any non-virtual method" here.

OK, thanks to you both. I had a misconception about this.
 

Re: Assigned and FreeAndNil

Quote
But of course this begs the question of whether the call to FreeAndNil is
even justified. In most cases it is *not*. It seems to me that many people
have latched on to FreeAndNil with almost superstitious awe - that it is
*somehow* going to make their code safer and leak proof and thus using it
everywhere instead of only where it is actually called for.
IMO, FreeAndNil is always justified. It is part of good defensive
programming, like using assertions to check valid input to methods.
for example, freeAndNil gives you extra compile-time checking. eg if you
have a procedure using a const parameter:
procedure doSomething(const aCar:TCar);
begin
showMessage('the car is:'+aCar.color);
aCar.free;
end;
that will compile just fine, yet give you a bug that might be very hard
to track down. (the memory referenced by the tcar instance isn't
cleared, so subsequent access to the now-invalid pointer may actually
succeed, making the situation even worse, and even harder to track down).
compared to this, a more robust implementation, which will give a
compile-time error:
procedure doSomething(const aCar:TCar);
begin
Assert(aCar<>nil);
showMessage('the car is:'+aCar.color);
FreeAndNil(aCar);
end;
This is even more important and useful when refactoring code.
 

Re: Assigned and FreeAndNil

..But I really didn't know it. ;-)
I thought this would be only possible for class methods.
To sum it up for me and others: This all works:
TTest = class
private
protected
public
class function GetClassVersion:Integer;
function GetVersion:integer;
function GetVersionVirtual:integer; virtual;
published
end;
.....
class function TTest.GetClassVersion: Integer;
begin
Result:=2;
end;
function TTest.GetVersion: integer;
begin
Result:=2;
end;
function TTest.GetVersionVirtual: integer;
begin
Result:=2;
end;
procedure TForm1.Button1Click(Sender: TObject);
var MyTest:TTest;
begin
writeln(TTest.GetClassVersion);
writeln(MyTest.GetVersion);
MyTest:=TTest.Create;
writeln(MyTest.GetVersionVirtual);
MyTest.free;
end;
 

Re: Assigned and FreeAndNil

Assumption #1: "If variable is nil most of the time then" then probably it
is worth to check
Assumption #2:
Quote
And now assume that the variable is not nil in most cases...
then you do not need to check...
as I said you do not have to check, but you could... and "code is not safer"
it is chicken and egg situation.
"we need to put "if Assigned(x) then" in front of every call to
"FreeAndNil(x)"" (I did not hear "why" answered here) versus "FreeAndNil(x)
is safe by it self" is not opposite statements...
They just represent different view of the code usage - simplistic and
minimalistic.
 

Re: Assigned and FreeAndNil

In article <45403d57$XXXX@XXXXX.COM>, John Jacobson says...
Quote
I have a disagreement with a fellow programmer about how FreeAndNil works in
Win32 Delphi.
I have heard it argued that Assigned() being equivalent to <>NIL is a
platform specific implementation detail.
i.e. it is possible that the code, when compiled on some other platform,
may fail if the test for being Assigned did not involve a test for non-
NILness.
Quote
we don't need to,
because FreeAndNil(x) will do the test for nil in the Free code that gets
called.
Ah, this was actually point of the delusional fools offering the
platform specific argument.
If you look at TObject.Free, it doesn't use Assigned() to test self, it
checks directly for non-NILness.
So in theory they were right - in the future a call to FreeAndNIL(NIL)
or NIL.Free might fail if on that future platform Assigned'ness was not
related to NIL'ness and for some reason .Free did not perform an
Assignedness test appropraite to that platform.
At least, I think that was what was keeping them awake at nights
So yes:
if Assigned(x) then FreeAndNil(x);
is safer than:
FreeAndNil(x);
The more pertinent question is, is the risk that you are avoiding ever
likely to be an issue?
I don't think it needs a rocket scientist to answer that one!!
--
Jolyon Smith
 

Re: Assigned and FreeAndNil

If you can not beat 'em, join 'em. Concede the point but then tell him that to
be even safer, the code should look like this:
if Assigned(x) then
FreeAndNil(x)
else
x := nil;
Because if by some chance X was not assigned to begin with, then
FreeAndNil() will never get called and therefore X will never get set to
nil.
"John Jacobson" <jake@j[nospam]snewsreader.com>writes
Quote

What think ye? In teh valued opinion of the readers of this fine newsgroup
is this...

if Assigned(x) then FreeAndNil(x);

...actually any safer than

FreeAndNil(x);
 

Re: Assigned and FreeAndNil

Bob Dawson writes:
Quote
"Ben604" wrote
>obj := TObject.Create;
>obj.Free;
>FreeAndNil(obj);
>
>The above will cause a Invalid Pointer operation

But so would

obj := TObject.Create;
obj.Free;
if assigned(obj) then
FreeAndNil(obj);

the redundant assigned check adds nothing.

bobD
I stand corrected. Dunno how, but I have run into issues not checking
Assigned before and have been doing it ever since.
 

Re: Assigned and FreeAndNil

On Wed, 25 Oct 2006 23:45:14 -0500, "John Jacobson"
<jake@j[nospam]snewsreader.com>writes:
Quote
What think ye? In teh valued opinion of the readers of this fine newsgroup
is this...
Show him the asm.
- Asbjørn
 

Re: Assigned and FreeAndNil

Don Strenczewilk writes:
Quote
if Assigned(x) then
FreeAndNil(x)
else
x := nil;
LOL -- that is brilliant!
Of course, an excessively careful programmer would use:
if (Assigned(x)) or (x <>nil) then
begin
FreeAndNil(x)
end else
begin
x := nil;
end;
Because, after all, one can not be sure that Assigned() actually is doint
what it is supposed to be doing. ;-)
--
Nick Hodges
Delphi/C# Product Manager - Borland DTG
blogs.borland.com/nickhodges
 

Re: Assigned and FreeAndNil

"David Clegg" wrote
Quote

I do it out of habit and consistency for the times where I'm
freeing an object which may have greater scope.
Don't you know whether it has greater scope?
Sorry, that sounds a lot like always coming to a full stop at a lighted
intersection out of habit and consistency for the times when the light is
red. <g>
bobD
 

Re: Assigned and FreeAndNil

Bob Dawson writes:
Quote
Don't you know whether it has greater scope?
Of course I do. it is more about taking a consistent approach in my
code, and being doubly sure that you're not going to be caught out, or
catch out a less experienced co-worker who may be maintaining the same
code base with you.
I also think you have a valid point about FreeAndNil becoming less
relevant in an OO environment, which is a place I have been trying to
gravitate towards more and more over the last few years.
Quote
Sorry, that sounds a lot like always coming to a full stop at a
lighted intersection out of habit and consistency for the times when
the light is red. <g>
Heh! I guess it it kinda does boil down to that. :-)
It's threads like this that illustrate exactly why I am constantly
re-evaluating and challenging my current coding style. Ideas that seem
like no-brainers at the time of adoption often don't make quite as much
sense on reflection, especially as more knowledge and experience is
gained.
--
Cheers,
David Clegg
XXXX@XXXXX.COM
cc.borland.com/Author.aspx
QualityCentral. The best way to bug Borland about bugs.
qc.borland.com
"Who is Fonzy!?! Don't they teach you anything at school?" - Homer
Simpson
 

Re: Assigned and FreeAndNil

theo writes:
Quote
...But I really didn't know it. ;-)
I thought this would be only possible for class methods.
Class methods are designed for working without objects, but other
methods work as well without objects, unless they try to dereference the
Self reference.
Quote

To sum it up for me and others: This all works:
[...]
procedure TForm1.Button1Click(Sender: TObject);
var MyTest:TTest;
begin
You should add here:
MyTest := nil;
Otherwise these lines produce random results:
Quote
writeln(MyTest.GetVersionVirtual);
MyTest.free;
DoDi
 

Re: Assigned and FreeAndNil

Quote
Because, after all, one can not be sure that Assigned() actually is doint
what it is supposed to be doing. ;-)
Well to be sure:
try
if (Assigned(x)) or (x <>nil) then
begin
try
FreeAndNil(x)
except
x.Free;
x:=nil;
end;
end else
begin
x := nil;
end;
finally
x:=nil;
end;
Oliver Townshend