1

In our application framework we have some kind of instance handler class that in resume it's responsible for capture the instances create by our others controllers/components/forms/etc.

Here's the declaration:

TInstanceHandler = class(TFrameworkClass)
strict private
  FInstances : TList<TObject>;
  procedure FreeInstances();
protected
  procedure Initialize(); override;
  procedure Finalize(); override;
public
  function Delegate<T : class>(const AInstance : T) : T;
end;

And the implementation:

procedure TInstanceHandler.FreeInstances();
var AInstance : TObject;
begin
  for AInstance in FInstances do
    if(Assigned(AInstance)) then AInstance.Free();
  FInstances.Free();
end; 

procedure TInstanceHandler.Initialize();
begin
  inherited;
  FInstances := TList<TObject>.Create();
end;

procedure TInstanceHandler.Finalize();
begin
  FreeInstances();
  inherited;
end;

function TInstanceHandler.Delegate<T>(const AInstance : T) : T;
begin
  FInstances.Add(AInstance);
end;

what happen sometimes is that our programmers forgot the existence of this class or his purpose and they free their instances.

Like this:

with InstanceHandler.Delegate(TStringList.Create()) do
  try
    //...
  finally
    Free();
  end;

what happens next is that when TInstanceHandler is finalized it will try to free the delegated instance again and this will lead to a error. I know the season why Assigned fail in this case and as far i can see i cant use FreeAndNil.

so the question is: how i can correctly check if the reference was already freed?

LU RD
  • 34,438
  • 5
  • 88
  • 296
kabstergo
  • 761
  • 4
  • 16
  • 1
    Why are you not using TObjectList ? – whosrdaddy Mar 05 '15 at 15:52
  • @whosrdaddy `TObjectList` will lead to the same error, thats why i attemped to change to the `TList` so i could detect what should be free – kabstergo Mar 05 '15 at 15:57
  • I see, anyway as David stated, there is no way out in this case. – whosrdaddy Mar 05 '15 at 15:59
  • `if(Assigned(AInstance)) then AInstance.Free()` should be `AInstance.Free()` and your Delegate method is meant to return a value and doesn't. – David Heffernan Mar 05 '15 at 16:10
  • possible duplicate of [How to detect "dangling pointers" if "Assigned()" can't do it?](http://stackoverflow.com/questions/8598408/how-to-detect-dangling-pointers-if-assigned-cant-do-it) – Jerry Dodge Mar 05 '15 at 20:54

1 Answers1

4

How I can correctly check if the reference was already freed?

You cannot.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • simple as that? no workaround or something? what i tried to do here was use `try` `except` in the `for` to keep execution running even after `free` raised a error but for my suprise i got a leak at the end of the application `EInvalidPointer` – kabstergo Mar 05 '15 at 15:42
  • 4
    Yes, simple as that. The object can be freed and now any attempt to de-reference your reference to it, which is just a pointer, is an error. In the meantime another object of that type may have been allocated by the memory manager re-using that address. How can you tell it apart from the old one that you deleted by mistake. The moral of the story is, the programmer has to follow the rules. There are some rules that cannot be enforced by the framework. Automatic reference counting would deal with all of this but perhaps that's not available to you. – David Heffernan Mar 05 '15 at 15:48
  • i see, i agree that is not the responsibility of the framework too, what happen is that sometimes ppl are a pain and they tend to not be responsable thats why i tried to implement this on the framework. anyway thx – kabstergo Mar 05 '15 at 15:54
  • 1
    Anyway, the answer to your question is exactly as I said. But there may well be alternative ways of designing your framework that solve the underlying problem. – David Heffernan Mar 05 '15 at 15:57
  • since you know the purpose of this class, care to indicate what are this alternatives so i can achieve that? – kabstergo Mar 05 '15 at 16:02
  • Well, whilst I can see what the class is doing, I'm not sure what motivated its creation. I don't have anything like this and I've never had any real problems keeping track of my references. So I wouldn't like to offer advice with my current state of ignorance. – David Heffernan Mar 05 '15 at 16:09