Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2019-05

Checking if a TStringList already exists

14 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

James Richters

I’m wondering if there is a way to test if a tstringlinst has been created yet?

I looked at the documentation in these two locations:

https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tstringlist.html

and

https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tstrings.html

but they do not show things like the .Create or .Free procedures, so I am thinking .Create and .Free are some kind of fundamental procedures that are used by generally everything in ‘classes’ maybe so if there was some function that would tell me if the TStringList existed, it would be in with .Create and .Free…. But I’m not sure where that would be documented.

Also can someone explain that the purpose of .Destroy is and why I would use .Free Vs .Destroy ?

James

Reply by email

Michael Van Canneyt
to James Richters
James Richters wrote 19 lines
I’m wondering if there is a way to test if a tstringlinst has been created yet? I looked at the documentation in these two locations: https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tstringlist.html and https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tstrings.html but they do not show things like the .Create or .Free procedures, so I am thinking .Create and .Free are some kind of fundamental procedures that are used by generally everything in ‘classes’ maybe so if there was some function that would tell me if the TStringList existed, it would be in with .Create and .Free…. But I’m not sure where that would be documented.

.Create and .Free are indeed fundamental constructors and destructors for classes. They are documented in the ancestors of TString(List).

A stringlist (or an object in general) exists if it is non-nil:

Procedure DoSomething(var A : tStringList);
begin
   if A=Nil then
     A:=TStringList.Create;
end;
Also can someone explain that the purpose of .Destroy is and why I would use .Free Vs .Destroy ?

.Free Can be called on a Nil instance (if the list does not exist yet)

so:
A.Free;
will check if A is non-nil, and calls A.Destroy if this is the case. If you call .Destroy in a nil instance, errors will occur.

Note that Free or Destroy will free the instance, but will NOT set the instance pointer to Nil.

So in the Above example:

A:=TStringList.Create;
A.Free;
if ANil then
   Writeln('A not nil');

will print
A not nil.

If you want to nil the pointer (recommended practice) then you should use FreeAndNil:

FreeAndNil(A);

Meaning that

A:=TStringList.Create;
FreeAndNil(A);
if ANil then
   Writeln('A not nil');

Will not print anything.

Michael.

Reply by email

James Richters
to Michael Van Canneyt

Thank you very much for the explanation and examples of this! I am glad you pointed out the FreeAndNill() function, I will defiantly be needing that.

James

Earlier message 77 lines
-----Original Message----- From: fpc-pascal On Behalf Of Michael Van Canneyt Sent: Monday, May 20, 2019 8:03 AM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] Checking if a TStringList already exists On Mon, 20 May 2019, James Richters wrote: > I’m wondering if there is a way to test if a tstringlinst has been created yet? > > > > I looked at the documentation in these two locations: > > https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tstringlist.html > > and > > https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tstrings.html > > > > but they do not show things like the .Create or .Free procedures, so I > am thinking .Create and .Free are some kind of fundamental procedures that > are used by generally everything in ‘classes’ maybe so if there was some > function that would tell me if the TStringList existed, it would be in > with .Create and .Free…. But I’m not sure where that would be documented. .Create and .Free are indeed fundamental constructors and destructors for classes. They are documented in the ancestors of TString(List). A stringlist (or an object in general) exists if it is non-nil: Procedure DoSomething(var A : tStringList); begin if A=Nil then A:=TStringList.Create; end; > Also can someone explain that the purpose of .Destroy is and why I would use .Free Vs .Destroy ? .Free Can be called on a Nil instance (if the list does not exist yet) so: A.Free; will check if A is non-nil, and calls A.Destroy if this is the case. If you call .Destroy in a nil instance, errors will occur. Note that Free or Destroy will free the instance, but will NOT set the instance pointer to Nil. So in the Above example: A:=TStringList.Create; A.Free; if ANil then Writeln('A not nil'); will print A not nil. If you want to nil the pointer (recommended practice) then you should use FreeAndNil: FreeAndNil(A); Meaning that A:=TStringList.Create; FreeAndNil(A); if ANil then Writeln('A not nil'); Will not print anything. Michael.

Reply by email

Sven Barth
to James Richters: Thank you very much for the explanation and examples of this! I am glad you pointed out…

James Richters schrieb am Mo., 20. Mai
2019, 15:23:

Thank you very much for the explanation and examples of this! I am glad you pointed out the FreeAndNill() function, I will defiantly be needing that.

Though you need to keep in mind that only that single variable will be set to Nil. Should there be other variables or fields that point to the same object instance they will stay as non-Nil.

Regards,
Sven

Reply by email

Graeme Geldenhuys
to Giuliano Colla:
Giuliano Colla wrote
In some rare case when dealing with complex objects you might need FreeThenNil() in place of FreeAndNil().

As far as I'm concerned, that is such a broken concept! The developer already has the burden to free any memory that he/she allocates. With what you are saying, it is now expected from the developer to look at all source code, flip and coin to decide how complex it is (that will vary between developers) and then decide which Free(Then|And)Nil() function to call!? That should really be left up to the compiler and should be of no concern to the developer.

Or there is a much simpler answer - the code the developer is working on is severely broken and needs some refactoring and decoupling of dependencies.

Regards,
Graeme

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 15 lines
On 20/05/2019 11:01 pm, Giuliano Colla wrote: > In some rare case when dealing with complex objects you might need > FreeThenNil() in place of FreeAndNil(). As far as I'm concerned, that is such a broken concept! The developer already has the burden to free any memory that he/she allocates. With what you are saying, it is now expected from the developer to look at all source code, flip and coin to decide how complex it is (that will vary between developers) and then decide which Free(Then|And)Nil() function to call!? That should really be left up to the compiler and should be of no concern to the developer. Or there is a much simpler answer - the code the developer is working on is severely broken and needs some refactoring and decoupling of dependencies.

I'm with Graeme on this one.

FreeThenNil should never be necessary.
FreeAndNil() should be enough for all circumstances.

Michael.

Reply by email

James Richters
to Giuliano Colla:

I don’t seem to have FreeThenNil I’m using FPC 3.0.4RC1 I don’t use Lazarus.. maybe it’s a Lazarus thing… or maybe it’s in a different unit

plotdraw.pax.pas(20,7) Error: Identifier not found "FreeThenNil"

James

Earlier message 44 lines
From: fpc-pascal On Behalf Of Giuliano Colla Sent: Monday, May 20, 2019 6:01 PM To: Subject: Re: [fpc-pascal] Checking if a TStringList already exists Il 20/05/2019 15:23, James Richters ha scritto: Thank you very much for the explanation and examples of this! I am glad you pointed out the FreeAndNill() function, I will defiantly be needing that. James Then you might also appreciate the function Assigned. Assigned(P) returns true if P is non-nil, and false if P is Nil. Nothing fancy, just making the code more readable. >From fpc documentation: Program Example96; { Program to demonstrate the Assigned function. } Var P : Pointer; begin If Not Assigned(P) then Writeln ('Pointer is initially NIL'); ; If Not Assigned(P) then Writeln('Internal inconsistency') else Writeln('All is well in FPC') end. Giuliano P.S. In some rare case when dealing with complex objects you might need FreeThenNil() in place of FreeAndNil(). Give a look to https://lists.lazarus-ide.org/pipermail/lazarus/2011-April/062743.html -- Do not do to others as you would have them do to you.They might have different tastes.

Reply by email

Sven Barth
to James Richters

James Richters schrieb am Di., 21. Mai
2019, 15:48:

I don’t seem to have FreeThenNil I’m using FPC 3.0.4RC1 I don’t use Lazarus.. maybe it’s a Lazarus thing… or maybe it’s in a different unit

Correct, it's part of Lazarus.

Regards,
Sven

Reply by email

Giuliano Colla
to Michael Van Canneyt: I'm with Graeme on this one. FreeThenNil should never be necessary. FreeAndNil() should…

Il 21/05/2019 14:40, Michael Van Canneyt ha scritto:

FreeThenNil should never be necessary. FreeAndNil() should be enough for all circumstances.

In a perfect world maybe you're right. But if you're dealing with LCL, you'll find it sometimes necessary, less your program segfaults, because the freeing of some children is postponed, and when they're set free their parent is already dead. Maybe it's a matter of bad design of some LCL components or even of TApplication, but either you decide that to make your project work you must redesign significant parts of LCL or you give up and sadly take advantage of FreeThenNil().

Giuliano

Do not do to others as you would have them do to you.They might have different tastes.

Reply by email

Michael Van Canneyt
to Giuliano Colla
Giuliano Colla wrote 12 lines
Il 21/05/2019 14:40, Michael Van Canneyt ha scritto: > FreeThenNil should never be necessary. FreeAndNil() should be enough > for all circumstances. In a perfect world maybe you're right. But if you're dealing with LCL, you'll find it sometimes necessary, less your program segfaults, because the freeing of some children is postponed, and when they're set free their parent is already dead. Maybe it's a matter of bad design of some LCL components or even of TApplication, but either you decide that to make your project work you must redesign significant parts of LCL or you give up and sadly take advantage of FreeThenNil().

In that case the lazarus devels should fix whatever causes this.

Delphi does not have this after all, so it is possible to create a set of GUI components that does not need it. It may not be easy, but you cannot expect a user to find out through trial and error what he should be doing.

Michael.

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt

Hi,

Michael Van Canneyt wrote 5 lines
In that case the lazarus devels should fix whatever causes this. Delphi does not have this after all, so it is possible to create a set of GUI components that does not need it. It may not be easy, but you cannot expect a user to find out through trial and error what he should be doing.

I fully agree with what Michael said. You can't truly expect applications developer to trail and error what needs to be done. It's an LCL issue that the Lazarus project needs to fix. Delphi's VCL, fpGUI Toolkit and MSEide+MSEgui doesn't require this. Proof that LCL is doing something wrong or has a bad internal design that needs fixing.

Regards,
Graeme

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Mattias Gaertner
to Graeme Geldenhuys
Show quoted text 7 lines
[...] I fully agree with what Michael said. You can't truly expect applications developer to trail and error what needs to be done. It's an LCL issue that the Lazarus project needs to fix. Delphi's VCL, fpGUI Toolkit and MSEide+MSEgui doesn't require this. Proof that LCL is doing something wrong or has a bad internal design that needs fixing.

I don't know what is wrong, with keeping a reference while it is being destroyed.
Is this some kind of "my design pattern is better than yours"?

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 13 lines
On Tue, 21 May 2019 16:47:28 +0100 Graeme Geldenhuys wrote: > [...] > I fully agree with what Michael said. You can't truly expect > applications developer to trail and error what needs to be done. It's > an LCL issue that the Lazarus project needs to fix. Delphi's VCL, > fpGUI Toolkit and MSEide+MSEgui doesn't require this. Proof that LCL > is doing something wrong or has a bad internal design that needs > fixing. I don't know what is wrong, with keeping a reference while it is being destroyed.

Because this should not matter.

By itself there is nothing wrong with it.

The point is that as a user, how am I supposed to know that I must use this instead of FreeAndNil ?

IOW, why would you need this ? Why does it make a difference ? Why doesn't Delphi need this ?

Michael.

Reply by email