Well, it doesn't have to be a leak in your code. It could also be in the cocoa widgetset. Both possible.
From the info avail, I would at first guess widgetset.
Though that is not necessary true. Lets assume something is allocated during ShowModal. Maybe the memory for a string which is refcounted.
Then at some point you create another object that references the string, or you do some pointer stuff "new(Pstring)^ := TheStringFromModal". You leak that other object or pointer. Then you also leak that string.
Heaktrc does not realize that the string was leaked at that later time. HeapTrc only shows you where it was allocated.
Of course for the above to happen you would expect that other object/pointer to be in the list of leaks.
But now say, you have some code that writes to random memory (e.g. a dangling pointer). The data to which the pointer points no longer exists, so the pointer points to something else, that just happened to re-use that memory.
Now say again ShowModal allocetad mem (that would be ok). It stores a pointer to that mem (eg to the object). Then Later show modal would free that object.
But your code, writes nil to the dangling pointer. And that happens to be the same address as the above object. Then the modal code sees nil, and cannot free the object.
Admitted, not a likely case. But a possibility.
Leaks are tricky.
FreeAndNil may not always be needed. It does no harm either. (I heard arguments saying it does, and it may on a first glance look like that, but the great balance may be different. So its a matter what math you subscribe too)
If you do
Procedure Bar;
var Foo: TFoo;
begin
Foo := getObject():
if Foo <> nil then begin
dosomething;
Foo.Destroy
end;
end;
You can use Destroy because:
- You already ensured Foo <> nil
- Foo goes out of scope on the next line.
The remaining dangling pointer can never be accessed.
If you did not have "if Foo <> nil then begin" then you would maybe use
Foo.Free;
because Foo maybe nil, and Free cares about that.
But in both cases you can also do FreeAndNil.
1) It does not hurt (unless you need code so time critical you should write it in asm instead)
2) Always using FreeAndNil means you will not accidentally NOT use it in other places
3) Foo is now a local var. What if you refactor it to be a field on "self" or a global var? Then you have to remember to change to FreeAndNil.
There is the argument that your code should be correct, and not even try to access the variable, if it is not assigned, or if the assigned object has been freed. And maybe that is how you designed it. But even then, bugs happen, and FreeAndNil may prevent them.
If you want to catch them, then write your own function
FreeThenBadPointer
and set the variable to pointer(-1).
If your code accesses the var, where it should not, then it will crash and you know you got an error.
In some case you want to use FreeThenNil. But that is a diff story.