Is there, besides hunting for memory leaks, another situation where I should free all objects when destroying an application? - delphi

Suppose an application with some forms and only one data module are created at start.
In the DM1.OnCreate event, a TStringList is created to be used at runtime.
We know that when the application is being terminated, all things will be destroyed and memory will automatically freed. Freeing something can take some time, and so is not always advised to worry about memory leaks on shutdown. See for example this answer from Barry Kelly or this post from Raymond Chen.
Beside that, FastMM reports the memory leak if I don't add TStringList.Free to DM1.OnDestroy. This turns out to be a problem when searching for any other memory leaks that I should really worry about.
So basically I am asking if/why/when I should free object instances that will be freed by application or OS (Windows in this specific case). Is there any other valid case that is not when hunting for memory leaks?
NOTE: In this specific case, the data module is not created or recreated more times. There will not be any memory leak at all, besides the one. The data module scrap source:
unit UDM1;
interface
uses SysUtils, Classes, ...;
type
TDM1 = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure DoStuffWithStringList1(Sender: TObject);
private
internalStL: TStringList;
end;
var
DM1: TDM1;
implementation
procedure TDMInterfacePAFECF.DataModuleCreate(Sender: TObject);
begin
internalStL := TStringList.Create();
end;
procedure TDMInterfacePAFECF.DataModuleDestroy(Sender: TObject);
begin
internalStL.Free; //<-- IS THIS NECESSARY OR ADVISED?
end;
procedure DoStuffWithStringList(Sender: TObject);
begin
//Place some code using internalStL here...
end;

For the same reason I strongly advocates (understatement) for not leaving any Compiler Hint or Warning in a project, clean after yourself and DO NOT LEAVE A REPORTED MEMORY LEAK!
EVER!
Now, that does not necessarily means that you have to Free everything in the Destructor of your DataModule if you have a strong case for not doing it, but in that case, you need to register your Memory Leak so that it will not be reported. (And put there a very visible comment to justify and explain why)
But consider the fact that you may leave this project and a year from now, someone else is maintaining it and has a new business requirement to create multiple DataModules... Chances are that if they do not know the inside of your code well enough, they will trust your code to be clean and problems are likely to follow.
So I would strongly advise against not freeing unless in a very special and expected and documented case...
PS: Seen that and had to mop up the memory dripping all over the place so many times that I even did some CodeRage sessions on fighting memory leaks...
Updayte: Here's the link to download that CodeRage session...

My answer can be considered philosophical, but the main reason is that any action (or absence of it) has consequences. I thought about your example and probably other examples and I see one good reason to free the object. Every time I think I can ignore freeing object increases the probability of not doing this in other, maybe more serious situation. Another example is a habit of doing "try finally end" everywhere something is allocated or freed. I don't care about freeing in case of exception, but this habit helps me avoid leaking

Use RegisterExpectedMemoryLeak for the intentional memory leaks. The routine has a few overloaded versions of which one can be fead with an object class:
begin
RegisterExpectedMemoryLeak(TStringList);
FStringList := TStringList.Create;
...
or better, register the pointer itself:
begin
FStringList := TStringList.Create;
RegisterExpectedMemoryLeak(FStringList);
...
In this case the unexpected memory leaks will show up normally and can not be confused with this particular string list.

Let me answer by asking you a question.
Can you say for certain that the life cycle of the data module will always be tied to the lifetime of the application or that you will never need to create additional instances of it?
If you answer yes then feel free to ignore standard memory management practices.
If you answer no then you should make sure object's clean up after themselves.

Stuff gets done when you free an object, possibly more then only deallocating the memory.
Comes to mind a database object that does transactions and ends all started transactions in the ondestroy.
If you don't call free, ondestroy will not get fired and you may end up with locked tables.

Related

Memory management of interfaces in Delphi

I am struggling to learn delphi and memory management, coming from C#.
The current incarnation of that struggle is that I don't know the right way to dispose of the objects when I am done with them. From reading and my experiments it seems that if I have an object that is cast as an interface, then my ONLY choice is set the reference to nil.
If I go an call
FreeAndNil()
I end up getting an access violation, EX:
var
foo: IFoo;
begin
foo := TFoo.Create();
FreeandNil(foo);
end;
Sure, all I need to do it change that foo:IFoo; to foo:TFoo; and it is happy. OR simply set the pointer to nil, NOT call freeandNil.
foo := nil;
So, on one level, I don't understand in the least where the AV is.
On a differently level, I want to write the code such that it does not need to know if it is an interface or an object. I want to be able to write all of my memory management the same exact way, but I can't seem to write a method that can deal with something that is a Class or an interface. Well, that is not true, I do have something, but it is so ugly I hesitate to post it.
But I guess I should also be asking, what is everyone else doing? Mentally keeping track of what is an interface and just nil those pointers? otherwise calling FreeAndNil?
I am going to want to implement things the first time around as a concrete class, but later come back and change that to an interface when I find some way that the code can do from 2 different ways. And I am not going to want to go through the code and change how it was dealing with that reference, that is the last thing on my mind at that point.
But for the sake of discussion, the best (almost only) idea I have is this class:
interface
type
TMemory = class(TObject)
class procedure Free(item: TObject); overload; static;
class procedure Free<T: IInterface>(item: T); overload; static;
end;
implementation
uses
System.SysUtils;
{ TMemory }
class procedure TMemory.Free(item: TObject);
begin
FreeandNil(item);
end;
class procedure TMemory.Free<T>(item: T);
begin
//don't do anything, it is up the caller to always nil after calling.
end;
Then I can consistently call:
TMemory.Free(Thing);
Thing := nil;
Test code:
procedure TDoSomething.MyWorker;
var
foo: IFoo;
fooAsClass: TFoo;
JustAnObject: TObject;
begin
foo := TFoo.Create();
fooAsClass := TFoo.Create();
JustAnObject := TObject.Create();
TMemory.Free(foo);
foo := nil;
TMemory.Free(fooAsClass);
fooAsClass := nil;
TMemory.Free(JustAnObject);
JustAnObject := nil;
end;
runs with no leaks or access violations. (using MadExcept)
But a big thank you to the Delphi community on SO. You guys have been the best thing out there for learning!
The reason for the access violation is that FreeAndNil takes an untyped parameter, but expects it to be an object. So the method operates on the object.
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj); //Obj must be a TObject otherwise all bets are off
Pointer(Obj) := nil; //Will throw an AV if memory violation is detected
Temp.Free; //Will throw an AV if memory violation is detected
end;
A memory violation in the above might (NB not guaranteed) be detected if you destroy an object that has either been previously destroyed or never created. It's also likely to be detected if Obj doesn't reference an object at all but something else (such as an interface, record, Integer because these don't implement Free and if they did, it wouldn't be located in the same way as TObject.Free).
On a differently level, I want to write the code such that it does not need to know if it is an interface or an object. I want to be able to write all of my memory management the same exact way.
This is like saying you want to use your car in exactly the same way that you use your shower.
Ok, maybe the difference is not quite that extreme. But the point is that interfaces and objects (and for that matter records) use different memory management paradigms. You cannot manage their memory in the same way.
Objects need to be explicitly destroyed. You can use an ownership model, but destruction is still an explicit external action.
Interfaces are reference counted. The compiler injects code to track the number of fields and variables referencing (looking at) the underlying instance. Typically the object destroys itself when the last reference is released. (There are ways beyond the scope of this answer to change this.)
If we access some object by interface variable, it doesn't always mean that object is destroyed the moment reference counter drops to zero. For example, TComponent methods _AddRef and _Release implementations are 'dummy': no reference counting is implemented and TComponent is never destroyed because interface variables are out of scope.
To behave as we expect from 'real' interfaces, all your objects should be descendants from TInterfacedObject or you need to implement _AddRef / _Release yourself.
Yes, there are 2 different approaches to memory management which usually co-exist in a program, but confusion (and AV) arises only when the same object is treated in both ways. If we destroyed object and only then the interface variables have gone out of scope, they call _Release method of destroyed object which causes access violation. That's some risky business, though with some attention it is doable.
Classic Delphi components are not reference-counted, the concept of ownership is used instead. Each component has an owner whose responsibility is to free all the memory when it itself is destroyed. So each component has an owner, but it may also have a lot of pointers to another components, like when Toolbar has ImageList variable. If such components were refcounted, they would never be destroyed because of circular reference, so in order to break this circle you'd need 'weak' references as well which don't 'count'. They are here, too, but that's very recent feature of Delphi.
If there is some hierarchy in your objects, so you know that 'bigger' objects need all of 'smaller' ones to function, then use this good old approach, it's pretty simple and has very good implementation in Delphi, which is: you can make a code which will be leak-free no matter where exception could arise. There are all these little things like using .Free instead of .Destroy, because if exception happened in constructor, destructor is called automatically, and so on. Very clever solution in fact.
I'd use refcounted interfaces only if you don't know for how long some object is needed for you and there is no suitable 'owner' for it. I did it with scanned image which I saved to file in one thread, while converting to smaller image to show on screen on another thread. When all is done, image is no more needed in RAM and can be destroyed, but I have no idea which happens first. In this case using refcounting is best thing to do.

How to debug a (possible) RTL problem?

I'm asking this because I'm out of good ideas...hoping for someone else's fresh perspective.
I have a user running our 32-bit Delphi application (compiled with BDS 2006) on a Windows 7 64-bit system. Our software was "working fine" until a couple weeks ago. Now suddenly it isn't: it throws an Access Violation while initializing (instancing objects).
We've had him reinstall all our software--starting all over from scratch. Same AV error. We disabled his anti-virus software; same error.
Our stack tracing code (madExcept) for some reason wasn't able to provide a stack trace to the line of the error, so we've sent a couple error logging versions for the user to install and run, to isolate the line which generates the error...
Turns out, it's a line which instances a simple TStringList descendant (there's no overridden Create constructor, etc.--basically the Create is just instancing a TStringList which has a few custom methods associated with the descendant class.)
I'm tempted to send the user yet another test .EXE; one which just instances a plain-vanilla TStringList, to see what happens. But at this point I feel like I'm flailing at windmills, and risk wearing out the user's patience if I send too many more "things to try".
Any fresh ideas on a better approach to debugging this user's problem? (I don't like bailing out on a user's problems...those tend to be the ones which, if ignored, suddenly become an epidemic that 5 other users suddenly "find".)
EDIT, as Lasse requested:
procedure T_fmMain.AfterConstruction;
begin
inherited;
//Logging shows that we return from the Inherited call above,
//then AV in the following line...
FActionList := TAActionList.Create;
...other code here...
end;
And here's the definition of the object being created...
type
TAActionList = class(TStringList)
private
FShadowList: TStringList; //UPPERCASE shadow list
FIsDataLoaded : boolean;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
procedure DataLoaded;
function Add(const S: string): Integer; override;
procedure Delete(Index : integer); override;
function IndexOf(const S : string) : Integer; override;
end;
implementation
procedure TAActionList.AfterConstruction;
begin
Sorted := False; //until we're done loading
FShadowList := TStringList.Create;
end;
I hate these kind of problems, but I reckon you should focus on what's happening recently BEFORE the object tries to get constructed.
The symptoms you describe sound like typical heap corruption, so maybe you have something like...
An array being written to outside bounds? (turn bounds checking on, if you have it off)
Code trying to access an object which has been deleted?
Since my answer above, you've posted code snippets. This does raise a couple of possible issues that I can see.
a: AfterConstruction vs. modified constructor:
As others have mentioned, using AfterConstruction in this way is at best not idiomatic. I don't think it's truly "wrong", but it's a possible smell. There's a good intro to these methods on Dr. Bob's site here.
b: overridden methods Add, Delete, IndexOf
I'm guessing these methods use the FshadowList item in some way. Is it remotely possible that these methods are being invoked (and thus using FShadowList) before the FShadowList is created? This seems possible because you're using the AfterConstruction methods above, by which time virtual methods should 'work'. Hopefully this is easy to check with a debugger by setting some breakpoints and seeing the order they get hit in.
You should never override AfterConstruction and BeforeDestruction methods in your programs. They are not meant for what you're doing with them, but for low-level VCL hacking (like reference adding, custom memory handling or such).
You should override the Create constructor and Destroy destructor instead and put your initialization code here, like such:
constructor TAActionList.Create;
begin
inherited;
// Sorted := False; // not necessary IMHO
FShadowList := TStringList.Create;
end;
Take a look at the VCL code, and all serious published Delphi code, and you'll see that AfterConstruction and BeforeDestruction methods are never used. I guess this is the root cause of your problem, and your code must be modified in consequence. It could be even worse in future version of Delphi.
Clearly there is nothing suspicious about what TAActionList is doing at time of construction. Even considering ancestor constructors and possible side-effects of setting Sorted := False indicate there shouldn't be a problem. I'm more interested in what's happening inside T_fmMain.
Basically something is happening that causes FActionList := TAActionList.Create; to fail, even though there is nothing wrong in the implementation of TAActionList.Create (a possibility is that the form may have been unexpectedly destroyed).
I suggest you try changing T_fmMain.AfterConstruction as follows:
procedure T_fmMain.AfterConstruction;
begin
//This is safe because the object created has no form dependencies
//that might otherwise need to be initialised first.
FActionList := TAActionList.Create;
//Now, if the ancestor's AfterConstruction is causing the problem,
//the above line will work fine, and...
inherited AfterConstruction;
//... your error will have shifted to one of these lines here.
//other code here
end;
If an environment issue with a component used by your form is causing it destroy the form during AfterConstruction, then it's the assignment of the new TAActionList.Create instance to FActionList that's actually causing the AV. Another way to test would be to first create the object to a local variable, then assign it to the class field: FActionList := LActionList.
Environment problems can be subtle. E.g. We use a reporting component which we discovered requires that a printer driver is installed, otherwise it prevents our application from starting up.
You can confirm the destruction theory by setting a global variable in the form's destructor. Also you may be able to output a stack trace from the destructor to confirm the exact sequence leading to the destruction of the form.
Our software was "working fine" until a couple weeks ago... suddenly become an epidemic that 5 other users suddenly "find".) :
Sounds like you need to do some forensic analysis, not debugging: You need to discover what changed in that user's environment to trigger the error. All the more so if you have other users with the same deployment that don't have the problem (sounds like that's your situation). Sending a user 'things to try' is one of the best ways to erode user confidence very quickly! (If there is IT support at the user site, get them involved, not the user).
For starters, explore these options:
*) If possible, I'd check the Windows Event Log for events that may have occurred on that machine around the time the problem arose.
*) Is there some kind of IT support person on the user's side that you can talk to about possible changes/problems in that user's environment?
*) Was there some kind of support issue/incident with that user around the time the error surfaced that may be connected to it, and/or caused some kind of data or file corruption particular to them?
(As for the code itself, I agree with #Warran P about decoupling etc)
Things to do when MadExcept is NOT Enough (which is rare, I must say):
Try Jedi JCL's JCLDEBUG instead. You might get a stack traceback with it, if you change out MadExcept for JCLDEBUG, and write directly the stack trace to the disk without ANY UI interaction.
Run a debug-viewer like MS/SysInternals debugview, and trace output things like the Self pointers of the objects where the problems are happening. I suspect that somehow an INVALID instance pointer is ending up in there.
Decouple things and refactor things, and write unit tests, until you find the really ugly thing that's trashing you. (Someone suggested heap corruption. I often find heap corruption goes hand in hand with unsafe ugly untested code, and deeply bound UI+model cascading failures.)

Why should I use Free and not FreeAndNil in a destructor?

I have read A case against FreeAndNil but still don't understand why I cannot use this method in a class destructor ? Can anyone explain.
Update: I think the comment from Eric Grange was most useful for me. The link show that this is not obvious how to deal with it and it is mainly a matter of taste. Also the method FreeAndInvalidate was useful.
The problem with that is that many
seem to use FreeAndNil as some magic
bullet that will slay that mysterious
crash dragon. If using FreeAndNil() in
the destructor seems to solve a crash
or other memory corruption problems,
then you should be digging deeper into
the real cause. When I see this, the
first question I ask is, why is the
instance field being accessed after
that instance was destroyed? That
typically points to a design problem.
It argues that it hides the real problem you have. It must mean your code is accessing properties/fields/methods of an object that is already destroyed (the destructor is called). So instead of hiding the real problem with FreeAndNil you should really be solving the underlying problem.
This code below would not crash if you would use FreeAndNil PropertyA in the destructor of SomeObject. But it hides the real problem that SomeObject is used after it is destroyed. It is better to solve this design problem (accessing destroyed objects) instead of hiding it.
SomeObject.Free; // Destructor called
if Assigned(SomeObject.PropertyA) then // SomeObject is destroyed, but still used
SomeObject.PropertyA.Method1;
EDIT
On the other case, one could argue that if FreeAndNil is not used, the code would not crash either. Since even though the object is destroyed, the memory might not be reused and all structures might be in tact. The code above might even run without problems if Free is used to destroy PropertyA instead of FreeAndNil.
And if FreeAndNil was used to destroy SomeObject, you would also see the real problem no matter what the code in the destructor is.
So although I agree with the argument that it could hide the real design flaw and personally do not use FreeAndNil in destructors, it is not some magic bullet to discover such design flaws.
The issue is fairly easy to explain, and the contention around this issue is more subjective than objective. The use of FreeAndNil is simply unnecessary if the variable reference to the object being freed will go out of scope:
procedure Test;
var
LObj: TObject;
begin
LObj := TObject.Create;
try
{...Do work...}
finally
//The LObj variable is going out of scope here,
// so don't bother nilling it. No other code can access LObj.
//FreeAndNil(LObj);
LObj.Free;
end;
end;
In the above code snippet, nilling the LObj variable would be pointless, for the reason given. However, if an object variable can be instantiated and freed several times during the lifetime of an app, then it becomes necessary to check whether the object is indeed instantiated or not. The easy way to check this is whether the object reference has been set to nil. In order to facilitate that setting to nil, the FreeAndNil() method will both free the resources, and set nil for you. Then, in code you can check to see whether the object is instantiated with either LObj = nil or Assigned(LObj).
The case of whether to use .Free or FreeAndNil() in object destructors is a grey area, but for the most part, .Free should be safe, and nilling the references to sub-objects in the destructor should be unnecessary. There are various arguments around how to deal with exceptions in constructors and destructors.
Now pay attention: if you prefer to pick and choose whether to use .Free or FreeAndNil() depending on the specific circumstances outlined above, that's fine, but note that the cost of a bug due to not nilling a freed object reference that is subsequently accessed can be very high. If the pointer is subsequently accessed (object freed but reference not set to nil), it can happen that you are unlucky and the detection of memory corruption occurs many lines of code away from the access to the freed-but-unnilled object reference. This kind of bug can take a very long time to fix, and yes, I know how to use FastMM.
Therefore for some people, including me, it has become habit (a lazy one, perhaps) to simply nil all object pointers when they're freed, even when the nilling is not strictly necessary.
I tended to use FreeAndNil fairly often (for whatever reason) but not anymore. What made me stop doing this is not related to whether the variable needs to be nil afterwards or not. It is related to code changes, especially type changes of variables.
I got bitten several times after changing the type of a variable from TSomething to an interface type ISomething. FreeAndNil doesn't complain and happily continues doing its job on the interface variable. This sometimes lead to mysterious crashes which could not be immediately followed back to the place where it happened and took some time to find.
So I switched back to calling Free. And when I deem it necessary I set the variable to nil afterwards explicitly.
i hunted down a stackoverflow question talking about FreeAndNil and FreeAndInvalidate to mention that the Microsoft Security Development Lifecycle now recommends something similar to FreeAndInvalidate:
In light of the SDL recommendation above – and a number of real bugs related to reuse of stale references to deleted C++ objects...
The obvious choice of sanitization value is NULL. However there are downsides to that: we know that a large number of application crashes are due to NULL pointer dereferences. Choosing NULL as a sanitization value would mean that new crashes introduced by this feature may be less likely to stand out to a developer as needing a proper solution – i.e. proper management of C++ object lifetimes – rather than just a NULL check that suppresses the immediate symptom.
Also checks for NULL are a common code construct meaning that an existing check for NULL combined with using NULL as a sanitization value could fortuitously hide a genuine memory safety issue whose root cause really does needs addressing.
For this reason we have chosen 0x8123 as a sanitization value – from an operating system perspective this is in the same memory page as the zero address (NULL), but an access violation at 0x8123 will better stand out to the developer as needing more detailed attention.
So basically:
procedure FreeAndInvalidate(var obj);
var
temp : TObject;
const
INVALID_ADDRESS = $8123; //address on same page as zero address (nil)
begin
//Note: Code is public domain. No attribution required.
temp := TObject(obj);
Pointer(obj) := Pointer(INVALID_ADDRESS);
temp.Free;
end;

Which is preferable: Free or FreeAndNil?

What is the basic difference between Free and FreeAndNil?
Is FreeAndNil = Free + Nil?
When should I use Free and when should I use FreeAndNil?
See
delphibasics-FreeAndNil
docwiki.embarcadero-FreeAndNil
pages-freeandnil [Broken]
eurekalog-freeandnil
blogs.embarcadero (via Wayback Machine)
...
And have a look at the implementation:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
Examples
Consider the following code:
procedure TForm1.FormCreate(Sender: TObject);
var
bm: TBitmap;
begin
bm := TBitmap.Create;
bm.LoadFromFile('C:\Users\Andreas Rejbrand\Documents\RAD Studio\6.0\Demos\DelphiWin32\VCLWin32\Football\up.bmp');
bm.Free;
if Assigned(bm) then
bm.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\test.bmp')
else
ShowMessage('Cannot save! The bitmap does no longer exist!');
end;
This will create an error or an invalid (empty) bitmap on my desktop, because I try to use an object that has been freed. Yes, even though bm has been freed, it is still "assigned", i.e. bm still points to a memory adress, even though there is nothing (usable) there. To overcome this, one can set bm := nil, as a safeguard, Then assigned(bm) will return false, as one would want. More or less, FreeAndNil(bm) is a shorthand for bm.Free; bm := nil. The first statement frees all memory (and OS resources, CPU time etc. used by the object), and bm := nil sets the "pointer" bm to nil, so that bm no longer points to the place where the object used to be, but no longer is. This way you (and routines like assigned) will not get fooled to believe that there still is a bitmap object.
Discussion
Some say that you should always use FreeAndNil(foo) rather than foo.Free. Well, why not? The additional instruction foo := nil will probably not take too many nanoseconds to execute, and indeed assigned(foo) = false is a very nice property of a freed object. But then again, if you know what you are doing, and know that you will never use the foo object again after freeing it, then you could stick to just foo.free. Really, some would argue that in many cases (but not all), trying to use a variable of a freed object is a bug by itself. (Of course there are cases where you do this intentionally - you have an object foo that sometimes is assigned and sometimes is not.)
Basically, FreeAndNil sets the reference to nil and then frees the object. This marks it as unassigned. So the only reason you would need to use FreeAndNil is if your code is going to reuse the reference. If you're in a destructor or a finally block, freeing objects that you're never going to touch again, just use Free.
See Delphi Memory Management Made Simple for an example of when I did find it useful. Mghie's comment at the bottom is also worth reading.
I'll answer in a different way.
Maybe, filling your object reference with nil after freeing your object is not always a good idea.
That way, you do not have a distinction between a reference that was never used (and hence is nil), and a reference that has been used, but should not be used in the future.
So, filling it with a magic number (similar to what the FastMM memory manager can do with the content of blocks of memory when those blocks are freed).
--jeroen
#Bharat, the difference between Free and FreeAndNil is that in addition to free memory used by an object FreeAndNil sets the object reference to nil.
you can check theses links for discussions about use Free or FreeAndNil
A case against FreeAndNil
Don’t abuse FreeAndNil anymore
JWSCL and FreeAndNil
JWSCL and FreeAndNil Second Attempt
Even if doesn't seem to be much different than Free, FreeAndNil will help you a lot while hunting bugs in your code.
How it saves your ass (access after free)
Just think what happens if you DON'T use FreeAndNil and then somewhere in your code you access a freed object. If you are terrible lucky, your program will immediately crash when it runs home (yes that crash is a 'good' crash). If you are a bit unlucky it will crash in customer's computer.
But this is not all. If your re unlucky, the program will not crash immediately. Or it will never crash, instead it will read or ven worst write) random chunks of memory. This is where the real pain starts!
Will it harm your program?
As others already pointed, the FreeAndNil itself is not bad. The FreeAndNil function is not broken/obsolete or something like this and it will not corrupt your code.
It is a legitimate RTL function that frees and object and then puts its pointer to NIL.
Facts vs opinions
Some will argue that relying on FreeAndNil may lead or indicate a design flaw, but they cannot justify this in any way. It is just their personal option. On the other hand, a program that cranshes randomly and undebuggingly (he he... I just create a new word) because you refused to use FreeAndNil is a fact not an opinion.
Come on... even on local variables?
I use FreeAndNil EVEN on a local variable. Using it on a local variable seems POINTLESS since the variable vanishes as soon as you exit the procedure.
Think that you may at a later date add more code at the end of the procedure, AFTER the point where you freed the object; code that will (accidentally) try to access the freed object. If the object was NIL, BABUM, instant AV (example).
A resource hog?
Some super-conservative programmers may say this simple call will waste RAM and CPU resources. I like to deliver small/fast/monolithic applications too!
But I don't think that removing using FreeAndNil will waste more than few bytes of RAM and CPU cycles. It will not make a real difference in the day-by-day life.
When you think that a single graphic resource like a TButton glyph or your program's icon can take 50-300KB (and your program can have dozens of these) it is pointless to argue about the resources "wasted' by FreeAndNil.
Gods vs programmers
Some people may say they never ever accessed a free object (basically meaning they never make mistakes) so they don't need FreeAndNil in this case. Well, I am not a robot. I do mistakes. I am not afraid to recognize it.
Pros
Mason Wheeler already points to a article that shows the 'lazy creation' method that uses FreeAndNil that we all used one day: http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple
Cons
No actual/solid evidence.
Allen Bauer has an article named A CASE when FreeAndNil is your enemy suggesting that using the FreeAndNil in a very particular and special case (the destructor of a visual component) could be bad. There is no code attached to the article that we can compile, only some possible scenarios where FreeAndNil might cause problems.
Allen states that FreeAndNil should be replaced with better methods. For example with FastMM.
However, this discussion demonstrates (with compilable code) that FastMM fails while FreeAndNil saves the day.
Where is the proof?
At this point I would love to have even ONE SINGLE tiny piece of concrete/compilable code to show that FreeAndNil could do harm.
On the other hand, we do have plenty (see links) of examples that shows how FreeAndNil can save our ass.
For those that are against FreeAndNil please enlighten us, by posting some compilable code.

Delphi 2009 - Can an Interface Property Cause a Memory Leak?

I inherited an Intraweb app that had a 2MB text file of memory leaks as reported by FastMM4. I've got it down to 115 instances of one class leaking 52 bytes.
A brief description of the bad actor is:
TCwcBasicAdapter = class(TCwcCustomAdapter)
protected
FNavTitleField: TField;
function GetAdapterNav(aDataSet: TDataSet): ICwcCDSAdapterNav; override;
public
constructor Create(aDataSource: TDataSource; aKeyField, aNavTitleField: TField; aMultiple: boolean);
end;
and the interface is:
ICwcCDSAdapterNav = interface(IInterface)
Am I barking up the wrong tree, since the property is reference counted? Are there any circumstances where the interface property could keep the class from being destroyed?
Here is the implementation of the method above:
function TCwcBasicAdapter.GetAdapterNav(aDataSet: TDataSet): ICwcCDSAdapterNav;
var
AdapterNav: TCwcCDSAdapterNavBase;
begin
result := nil;
if Assigned(aDataSet) then begin
AdapterNav := TCwcCDSAdapterNavBasic.Create(aDataSet, FKeyField.Index, FNavTitleField.Index);
try
AdapterNav.GetInterface(ICwcCDSAdapterNav, result);
except
FreeAndNil(AdapterNav);
raise;
end;
end;
end;
with the class declared as:
TCwcCDSAdapterNavBase = class(TInterfacedObject, ICwcCDSAdapterNav)
FastMM should give you what is leaked and where it was created.
That would help narrowing it down to the real culprit: who is leaking what?
I'm not sure what really your question is?
Your code is incomplete or not the one in question: your class does not have an Interface property nor an Interface private Field, just a method that returns an Interface, which is harmless.
Edit: Without seeing the code of your Object implementing ICwcCDSAdapterNav, we can't tell if it is indeed reference counted.
If you don't descend from TInterfacedObject, chances are that it's not reference counted and that you cannot rely on this automagically freeing...
You may want to give a look at this CodeRage 2 session: Fighting Memory Leaks for Dummies. It mainly shows how to use FastMM to prevent/detect memory leaks in Delphi. Was for D2007 but still relevant for other versions.
You've got some good answers so far about how FastMM works. But as for your actual question, yes, interfaced objects can leak in two different ways.
Interfaces are only reference-counted if the objects they belong to have implemented reference counting in their _AddRef and _Release methods. Some objects don't.
If you have circular interface references, (Interface 1 references interface 2, which references interface 1,) then the reference count will never fall to 0 without some special tricks on your part. If this is your problem, I'll refer you to Andreas Hausladen's recent blog post on the subject.
If you are leaking 115 instances of that class, then it is that class that is being leaked. The memory occupied by that class, not the memory occupied by the things it refers to, is being leaked. Somewhere, you have 115 instances of TCwcBasicAdapter that you're not freeing.
Furthermore, properties don't store data, no matter they're interfaces or some other type. Only fields occupy memory (along with some hidden space the compiler allocates on the class's behalf).
So, yes, you are barking up the wrong tree. Your memory leak is somewhere else. When FastMM tells you that you have a memory leak, doesn't it also tell you where each leaked instance was allocated. It has that capability; you might need to adjust some conditional-compilation symbols to enable that feature.
Surely it's not only instances of that class that are leaking, though. FastMM should also report some other things leaking, such as instances of the class or classes that implement the interface.
Based on the function you added, I've begun to suspect that it's really TCwcCDSAdapterNavBase that's leaking, and that could be because of the atypical way you use for creating it. Does the exception handler in GetAdapterNav ever run? I doubt it; TObject.GetInterface never explicitly raises an exception. If the object doesn't support the interface, it returns False. All that exception handler could catch are things like access violation and illegal operations, which you really shouldn't be catching there anyway.
You can implement that function more directly like this:
if Assigned(FDataSet) then
Result := TCwcCDSAdapterNavBase.Create(...);

Resources