Recent

Author Topic: [SOLVED] To Free or not to Free. That is the question  (Read 3674 times)

pcurtis

  • Hero Member
  • *****
  • Posts: 951
[SOLVED] To Free or not to Free. That is the question
« on: April 18, 2021, 08:41:35 am »
If I create an object -

MyObject.Create;

Is it better to FreeAndNil(MyObject) or is MyObject.Free enough?

Do I have to free stringlists after I create them?

Thanks in advance.
« Last Edit: April 18, 2021, 10:30:07 am by pcurtis »
Windows 10 20H2
Laz 2.2.0
FPC 3.2.2

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: To Free or not to Free. That is the question
« Reply #1 on: April 18, 2021, 09:03:47 am »
1. FreeAndNil is basically and mostly a stop gap for sloppy programming: Use after Free.. But there are some - but rare - scenario's that warrant it.
Personally, if I have to use FreeAndNil to get a program working, I'd go through the code to find where I was sloppy: FreeAndNil all too often hides bugs. (Algorithmic bugs, that is)
(Now you know that I use it too,, Sometimes..  :-[ )
The cost is negligable, though, except in loops, but note my remark about hiding bugs: e.g. Use after free becomes indetectable...OTOH constructs like if assigned() become more reliable. (As well as object pooling)

2. Yes, you will need to free stringlists. TStringlist is a class so should be free'd.
« Last Edit: April 18, 2021, 09:29:55 am by Thaddy »
Specialize a type, not a var.

AlexTP

  • Hero Member
  • *****
  • Posts: 2384
    • UVviewsoft
Re: To Free or not to Free. That is the question
« Reply #2 on: April 18, 2021, 09:04:59 am »
No difference; but FreeAndNil is better sometimes- makes sure that obj becomes Nil and you won't reuse it.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: To Free or not to Free. That is the question
« Reply #3 on: April 18, 2021, 09:13:41 am »
No difference; but FreeAndNil is better sometimes- makes sure that obj becomes Nil and you won't reuse it.
Big difference, see my remarks above...
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: To Free or not to Free. That is the question
« Reply #4 on: April 18, 2021, 09:41:13 am »
A couple of links for further reading:
http://pages.cs.wisc.edu/~rkennedy/freeandnil
https://www.delphitools.info/2010/02/06/dont-abuse-freeandnil-anymore/
https://blogs.embarcadero.com/a-case-when-freeandnil-is-your-enemy/
The latter is recommended, I discussed this - in person - with Allen Bauer, former lead tech scientist for Delphi.
Op.Cit.:
"My point was that using FreeAndNil can sometimes appear to solve the actual problem, when in fact if has merely traded it for another, more insidious, hard to find problem. A problem that doesn’t bite immediately."

And he actually wrote FreeAndNil....A.K.A. NilAndFree.
(Because the global reference is nilled  before the local reference is destroyed)

If you own a Delphi 7 license with RTL sourcecode (professional upwards) you will find that FreeAndNil is declared, but otherwise never used..... Grep -E. It is used in the VCL, though.
I don't know about higher versions, although it seems XE2 is also not using it in the RTL either..
Note: quick Sunday morning check, I may have overlooked something here and there.
Relevant link : https://www.youtube.com/results?search_query=black+cadillac+blues
« Last Edit: April 18, 2021, 10:33:16 am by Thaddy »
Specialize a type, not a var.

pcurtis

  • Hero Member
  • *****
  • Posts: 951
Re: To Free or not to Free. That is the question
« Reply #5 on: April 18, 2021, 10:29:12 am »
Thanks for the info.
Windows 10 20H2
Laz 2.2.0
FPC 3.2.2

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: [SOLVED] To Free or not to Free. That is the question
« Reply #6 on: April 18, 2021, 10:34:37 am »
Check the last link I added for what happens if do do not pay attention (posts crossed)
Replace all references to women with FreeAndNil.. Enjoy.
(you will need some knowledge about southern USA slang to appreciate it.)
« Last Edit: April 18, 2021, 10:51:17 am by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: [SOLVED] To Free or not to Free. That is the question
« Reply #7 on: April 18, 2021, 07:37:21 pm »
Thaddy, you've only given references to one point of view. Here is an example for another one.
About the source code. I just did a search for FreeAndNil (whole word) in the Delphi Community sources - 2594 matches!

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: [SOLVED] To Free or not to Free. That is the question
« Reply #8 on: April 18, 2021, 08:01:21 pm »
Thaddy, you've only given references to one point of view.
Well, Allen Bauer is the author - both the routine and the blog post -. :o I rest my plea.

Sounds like Covid denial..... Facts are not open to opinion, you know that.
« Last Edit: April 18, 2021, 08:04:58 pm by Thaddy »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: [SOLVED] To Free or not to Free. That is the question
« Reply #9 on: April 18, 2021, 08:07:05 pm »
2594 matches!
But NOT in the Delphi RTL sources. Incompetence is not an art.
Of those 2594 hits, maybe, just maybe, 94 are relevant.

BTW I am not accusing you of incompetecance, I highly esteem your skills.
I am merely making a point.
« Last Edit: April 18, 2021, 08:11:12 pm by Thaddy »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: [SOLVED] To Free or not to Free. That is the question
« Reply #10 on: April 18, 2021, 08:42:27 pm »
@ASerge
The link you posted is a solid ground to dismiss the author if I were to employ him. :P :'( >:D
The good thing to learn from this is that a programmer should be a critic of his own code... Allen did...
« Last Edit: April 18, 2021, 08:52:37 pm by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: [SOLVED] To Free or not to Free. That is the question
« Reply #11 on: April 18, 2021, 10:50:04 pm »
But NOT in the Delphi RTL sources. Incompetence is not an art.
Of those 2594 hits, maybe, just maybe, 94 are relevant.
I realized that incompetence is just your opinion.
In RTL 103 matches. Compared to Delphi 7 (17 matches) this suggests that defensive coding and trying to avoid problems in large projects is perhaps more important than supposedly sloppy programming.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: To Free or not to Free. That is the question
« Reply #12 on: April 18, 2021, 11:05:20 pm »
1. FreeAndNil is basically and mostly a stop gap for sloppy programming: Use after Free..

I read the "A case against Freeandnil article" article again, and Alan never says anything like that. It says it is not a silver bullet to cover up problems, but he also says:

Quote
FreeAndNil itself isn’t the culprit here.

He seemed to be more ticked off at people at SO telling everybody that a .free is evil and I agree with that. But that doesn't automatically that we should invert this policy and reproduce a bunch of links like Thaddy does on every mention like freeandnil. That is even more destructive.


Jeroen Pluimers seems to care about accidentally passing interface references to it, and the general untypedness

True, but IMHO a very minor point.

Eric Grange wants to introduce a TObject(1) magic constant to avoid things. He refers to other links to list the problems however, and doesn't reiterate them.

In short, so while in odd cases, freeandnil can obscure, there is a lot of loose sand here, and there doesn't seem to be coherent direction.

I myself rely on freeandnil (and thus on checking if a reference has been freed) a lot during shutdown, when it is a protective layer to avoid generating a cascade of exceptions if something goes wrong in the various parts of the program (gui including opengl, mainprogram logic. Threads that might or might not interface hardware etc) and preferably get some reasonable copy of the program's state to disk.


Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: To Free or not to Free. That is the question
« Reply #13 on: April 19, 2021, 06:50:28 pm »
FreeAndNil is basically and mostly a stop gap for sloppy programming: Use after Free.. But there are some - but rare - scenario's that warrant it.

On a similar token, one might argue that even Free() can be seen as another helper that promotes sloppy programming.

The actual class destructor is Destroy(), not Free().  The only difference between them is that Free() checks for nil before then calling Destroy().  But most of the time, in code that manages its pointers correctly, a pointer will not be nil when Free() is called on it, eg:

Code: Pascal  [Select][+][-]
  1. SL := TStringList.Create;
  2. try
  3.   ...
  4. finally
  5.   SL.Free; // <-- SL is not nil here!
  6. end;

Which is essentially doing this:

Code: Pascal  [Select][+][-]
  1. SL := TStringList.Create;
  2. try
  3.   ...
  4. finally
  5.   if SL <> nil then SL.Destroy; // <-- nil check is redundant!
  6. end;

The primary reason that Free() even exists at all is to handle the case where a class' constructor raises an exception (and if you have a constructor that is raising exceptions, you likely have more important issues to worry about).  Its destructor still gets called, and needs to free any object members that were already constructed prior to the exception being raised, eg:

Code: Pascal  [Select][+][-]
  1. constructor TMyClass.Create;
  2. begin
  3.   inherited;
  4.   Member1 := TSomeClass.Create;
  5.   DoSomethingThatMayRaise;
  6.   Member2 := TAnotherClass.Create;
  7. end;
  8.  
  9. destructor TMyClass.Destroy;
  10. begin
  11.   if Member1 <> nil then Member1.Destroy; // <-- may be nil or non-nil
  12.   if Member2 <> nil then Member2.Destroy; // <-- may be nil or non-nil
  13.   inherited;
  14. end;

By exposing Free() as a wrapper for Destroy(), it makes writing a destructor a little easier so it doesn't have to know whether the constructor was successful or not, since all class members are zero'ed/nil'ed before the constructor is called.

Code: Pascal  [Select][+][-]
  1. constructor TMyClass.Create;
  2. begin
  3.   inherited;
  4.   Member1 := TSomeClass.Create;
  5.   DoSomethingThatMayRaise;
  6.   Member2 := TAnotherClass.Create;
  7. end;
  8.  
  9. destructor TMyClass.Destroy;
  10. begin
  11.   Member1.Free;
  12.   Member2.Free;
  13.   inherited;
  14. end;

So, it could be argued that Free() should only be called on a pointer that has the possibility of being nil when its object needs to be destroyed, otherwise Destroy() should be called directly.

But, the cost of calling Free() instead of Destroy() directly is usually negligable...
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: To Free or not to Free. That is the question
« Reply #14 on: April 19, 2021, 08:20:31 pm »
FreeAndNil is basically and mostly a stop gap for sloppy programming: Use after Free.. But there are some - but rare - scenario's that warrant it.

On a similar token, one might argue that even Free() can be seen as another helper that promotes sloppy programming.

The actual class destructor is Destroy(), not Free().  The only difference between them is that Free() checks for nil before then calling Destroy().  But most of the time, in code that manages its pointers correctly, a pointer will not be nil when Free() is called on it
I have to say that "features" that _hide_ bugs in program are not "desirable" features.  I think the programmer would be better off getting an access violation which would hopefully cause him/her to fix the error.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018