Procedure TMain.test;
var
List:TStringList;
begin;
List:=TStringList.Create;
// Do Soemthing
List.Destroy; //neccessary?
End;
Do I have to destroy the object or is it O.K. to rely on delphi to do it?
Thx
Wolfgang
Procedure TMain.test;
var
List: TStringList;
begin;
List := TStringList.Create;
try
// Do Soemthing
finally
List.Free;
end;
end;
The German Delphi Help (Keywords Destroy/Free) says:
"Es ist nicht ratsam, Destroy direkt aufzurufen. Verwenden Sie statt dessen
Free. Free überprüft, ob das Objekt nicht bereits freigegeben wurde, und
ruft Destroy nur bei Bedarf auf.
Mit Free wird ein Objekt freigegeben. Wenn die Objektinstanz nicht NIL ist,
wird Destroy aufgerufen. Alle zur Laufzeit instantiierten Objekte, die
keinen Eigentümer besitzen, sollten mit einem Aufruf von Free aufgelöst
werden, damit sowohl das Objekt als auch der zugehörige Speicher korrekt
freigegeben wird."
tom
Ing. Wolfgang Bures <Wolf...@bures.at> schrieb in im Newsbeitrag:
93s1tv$hm...@bornews.inprise.com...
| Delphi destroy local objects automatically, right?
|
| Procedure TMain.test;
|
| var
| List:TStringList;
|
| begin;
| List:=TStringList.Create;
| // Do Soemthing
| List.Destroy; file://neccessary?
procedure TMain.test;
var
List : TStringList;
begin;
List := TStringList.Create;
try
// Do Soemthing
finally
List.Free; // Necessary!!!
end;
end;
HTH
Regards,
Morten Ludvigsen
2-People Software
>Delphi destroy local objects automatically, right?
There are no local objects.
>Procedure TMain.test;
>
>var
> List:TStringList;
What you have created here is not a local object, but a local
variable, List, which is a pointer to a TStringList. It is just 4
bytes long, like any pointer.
>begin;
> List:=TStringList.Create;
Here *you* create (instantiate) the object. It is here that memory is
assigned to hold the object, and the adress of this memory is passed
back by the constructor (Create), and stored in List by your
assigment.
So it stands to reason that *you*, again, should free the memory
assigned for the object instantiation.
Manuel Algora
m...@encomix.es
I'd like to add my own two cents here with a question.
I completely agree with the point of using the scope of the objects, but
several make a point of the original poster using free instead of destroy.
In actuality, I always use the fre also (in the hope that Borland will fix
this problem and I won't have to change my code), but is it really critical
to do in a local variable situation like this? The free only checks that the
var object is not nill, not that it was created. In a local procedure,
there's usually junk in the local variable, so calling the free makes no
difference. This is one bug that has irked me since the turbo pascal days.
Mike Walsh
I think this is the part the original poster was getting confused about.
These 4 bytes are either a register or on the stack, so the variable will
indeed be discarded, in a sense, when it goes out of scope. But all that
means is that you no longer have a pointer to the object *you* created,
because that pointer went out of scope. You still need to free the object
*you* created, and so you'd better either do so in the procedure that
created it or pass it on to somewhere else that is sure to free it.
Paul :)
it's a typical requirement of C- and VB-programmers to Delphi, that
garbage collection should happen automatically. But why should it?
A local object-variable doesn't always have to hold a seperate instance.
I often use local object-variables to hold newly created objects, that
are to be added to lists or collections. Before I add them to those
lists (even TObjectList) I don't want to typecast them or reach them
only via the last pointer in the list (not thread safe though).
So a local variable of the correct type helps initialize and handle the
new instance before it gets inserted somewhere else.
<sarcasm on>
Now PLEASE don't let Delphi destroy my fine new object if the procedure
exits - PLEASE.
<sarcasm off>
I think it would be a task, too comlex and time consuming for a (fast)
compiler. It would have to distinguish between the author's intentions
and errors, by analyzing what happens to instances, assigned to local
variables.
In addition it leads to very clear code if you write
MyNewObject := TAnyClass.Create;
try
<Do nasty things with MyObject here>
finally
MyNewObject.Free; //FreeAndNil absolutely obsolete here
end;
Only, and asolutely exclusive, in this situation, I want the object to
be destoyed on exit.
And again: IT'S NOT A BUG. No one ever said, Delphi would clean up
memory on exit, except the local stack. And as we all know, objects
don't reside on the stack but on the heap (just pointers to objects may
reside on the stack).
Bye
Robert
"Ing. Wolfgang Bures" <Wolf...@bures.at> schrieb im Newsbeitrag
news:93s1tv$hm...@bornews.inprise.com...
I think you misunderstood me. I didn't mean that I wanted Delphi to do GC.
The code I write looks a lot like the stuff you put in. What I was referring
to was the fact that the local variables have junk in them when the
procedure starts up. For example, if you take your procedure and comment out
the extra lines and the declaration part, in a local procedure you'll
probably get an AV
{MyNewObject := TAnyClass.Create;}
try
{<Do nasty things with MyObject here>}
finally
MyNewObject.Free; //FreeAndNil absolutely obsolete here
end;
and BTW, personally, I'm not a C or VB programmer. I've tried both, but
prefer Delphi.
MikeWalsh
did you hear anybody saying it's a *stupid* question? It's a point that
comes up again and again and needs to be discussed (obviously).
Bye
Robert
>...I've tried both, but
> prefer Delphi.
That's all I wanted to hear :-))
Maybe I still didn't get your argument. Freeing a local variable (of
type object-pointer) is the worst case of coming to know, that it didn't
get initialized.
Okay, you could argue, object-pointers should have to be initialzed with
NIL, Integers with 0 and so forth. But sometimes (and more often than
you might think) it's wasted time to intialize local variables in
general and automatic. E.g.: the local variable shall hold the result of
a function call (whatever result it will be). If it is initialized
first, where's the advantage?
On the other hand, sober initialization in source means to document the
preconditions explicitely instead of trusting the compiler.
Bye
Robert
It's a point that
> comes up again and again and needs to be discussed (obviously).
*obviously*
>
> Bye
> Robert
Mike Walsh
I think my biggest problem was the fact the I had a rough day the other day,
and felt in the mode to argue with someone.
The point I was trying to make is that...
1) Why are people so insistant that programmers use the free statement
within a local scope variable? Since free only checks for a nil on the
object pointer, and since local vars aren't initialized, this is no better
than using destroy in this case. On the other hand, if you want to be able
to cut and paste, and move your code around (for changing circumstances, for
example) it's better to use the methods that are more reliable (even if only
a little)
2) I prefer to use code like you posted, I feel without a doubt that it is
better coding, and far less likely for errors. It would be better to
emphasize the better coding style with the try blocks and explain the uses
and limitations of free.
Mike