Jump to content
Paul Dardeau

Guidance on FreeAndNil for Delphi noob

Recommended Posts

Embarcadero hosted a youtube livestream the other day with MVPs. It was a debate on use of FreeAndNil. Being new to Delphi, I don't have any historical baggage (well, I do; but not on this particular topic) or preconceived notions of how it should be done. I was disappointed that the video didn't at least include a "if you're brand new to delphi, here's our recommendations on the use of FreeAndNil". Having said all that, can you suggest some best practices for someone who's new to Delphi on good use of FreeAndNil?

Share this post


Link to post
2 hours ago, Paul Dardeau said:

can you suggest some best practices for someone who's new to Delphi on good use of FreeAndNil?

Use it ONLY when you NEED it.

 

When freeing an object that is pointed at by a given pointer variable, and that variable may be used again later, then nil'ing that variable makes sense, as future code will be sensitive to what the variable is (or is not) pointing at.

 

But, if the pointer variable is not going to be used after freeing the object, then there is simply no point is nil'ing the variable.

  • Like 2

Share this post


Link to post

As usual, there is no correct answer. Just opinions/options.

 

Option 1: Just use FreeAndNil all the time.  This way, you don't have to think about it, you can code it up in the Delphi IDE auto-complete stuff (and other tools like MMX). It is doing a bit of extra work, and calling an extra method, but you would need to doctor up some very contrived examples to have the speed penalty from FreeAndNil make any kind of impact on your code performance.

 

Option 2: Use FreeAndNil if you free objects in the middle of a method when there is code executing afterwards and you are scared you may accidentally use the freed variable. Also use FreeAndNil in explicit cases where a valid state of an object variable is NIL. If you free objects as the last few lines of a method (or in a destructor) dont use FreeAndNil and rejoice at the nanoseconds of processing speed you have saved compared to option 1

 

Option 3: never use FreeAndNil. If you use FastMM there is an option on it to catch the use of freed memory. That option does slow down things quite a bit, but it works. That way, even if you reuse a freed object variable, FASTMM will throw an exception. Or, if you dont use FastMM then simply don't make coding errors 🙂 Seriously though, it can take ages to find errors stemming from using freed memory if you dont have FastMM debug mode on, and all the nanoseconds in the world saved from not using FreeAndNil is not worth the hours it will take you to find the bug. 

Edited by Dave Novo
  • Like 1

Share this post


Link to post

It is very likely that whatever decision you make now, you will adjust as you get more experience.  This is a topic without a true correct answer... it simply depends.  

 

If you want to be strict and always follow a single rule - then use FreeAndNill all the time.  After a while, you will wonder why you are doing that and you can revisit after you have some code in place.

 

For me, I only rarely use FreeAndNil - only when it is part of the normal logic that instance again could/will be read in the future and that I will need to know it's correct state.  (For example, treat nil as a special 'done' or 'not yet started' type flag.)

  • Like 1

Share this post


Link to post

I always use FreeAndNil, even if it is the last line of a method. Why? Because my code evolve, I can copy/paste it somewhere, add line,... If the object variable (Actually a pointer btw) is nullified, I'm sure I'll get and exception if I forgot I can no more use that object reference. The impact on performance is nearly null.

But all rules can be ignored sometimes...

Share this post


Link to post

FreeAndNil is something that you will need to use rarely (it might depend on the kind of code you are writing).  In places where your code needs it logically it will be obvious that you need it and everywhere else you can use Free.

 

The point that FreeAndNil can help you avoid errors and mistakes is full of holes. First, simple access after Free is usually easy to catch either by looking at the code (local variables) or by using memory manager in debug mode or other specialized tools. Next, FreeAndNil nils only single reference to the object instance. If you have multiple ones you will still have to deal with dangling pointers and you will need to learn how to use previously mentioned tools. Most of the problems with memory management in Delphi are caused by having multiple references to single manually managed object instance as such code is more complex. This is exactly the place where FreeAndNil cannot help you, but where using it will give you false sense of security.

 

Another reason against using it everywhere, is that it obscures the code intent. Logically, FreeAndNil means that variable will be reused and this is important information. If you use it everywhere, you will have mush harder time reading the code and understanding its intent. And code which is harder to understand is also harder to maintain in the long run. Of course, that can be solved with comments, but then you will have to use them everywhere or you will never know whether some comment is missing somewhere.

 

Manual memory management requires some discipline. thinking about the code you are writing enforces the discipline and makes you a better programmer. Taking the "easy" path where you will slap FreeAndNill everywhere just so you can avoid accidental mistakes and thinking is going to cost you at some point. Many existing codebases where it is used everywhere cannot be easily migrated to not using it as it can be hard to determine where it is needed and where it is not (except for local variables) and they need to continue using it indefinitely in all places, as the only thing worse than using FreeAndNil everywhere is using it randomly. Consistence in code is the king.  

 

In my codebase I have less than 50 places where I am using FreeAndNil (I cannot tell the exact amount as I have many smaller projects and it is not easy searching through them as some contain fixed VCL code which uses FreeAndAil a lot, so I cannot easily count usage in my files only)

 

One of the advantages of being a new Delphi developer is that you don't have a lot of existing code where FreeAndNil was used in places where it is not needed :classic_smile: and now is the right time for you to decide whether you want to pollute your code with FreeAndNil and stick with it forever or not.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×