Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access violation when freeing TObjectList

I have the following Delphi code:

destructor TXX_XXXX.Destroy;
var
i: Integer;
begin
  if Assigned(Allocations) then
  begin
    for i:=0 to (Allocations.Count - 1) do 
    begin
      try
      TXX_ALOC(Allocations.Items[i]).Free;
      except on Ex:Exception do
      begin
        OutputDebugString(PChar('Exception Error Message '+ Ex.Message));
      end;
      end;
    end;

        // Above code works well - no exception

        try
    FreeAndNil(Allocations); {Exception Here}
    except on E:Exception do
    begin
      OutputDebugString(PChar('Exception in xxxxxxxxx.pas'+E.Message));
    end;
    end;
  end;
  inherited;
end;

Access violation at address 4003AB4 in module 'Vcl50.bpl'. Read of address 2980BFFC

I know the access violation usually caused by

  1. free some object which has been freed before
  2. use some object without initialization

But here before I do the free, I checked Allocations is assigned. If I discard the exception handling, my application will throw a something is wrong error. Allocations is a TObjectList, if it is an array - I will doubt I didn't assign a length to the array, but it is a TObjectList.

Thanks a lot!

like image 746
spspli Avatar asked Nov 27 '22 14:11

spspli


1 Answers

A TObjectList usually takes care of destroying its content. Don't free your objects in this case. This will lead to an access violation when freeing the TObjectList because it tries to free the contained objects again.

This behavior of the object list can be controlled in its constructor:

constructor TObjectList.Create(AOwnsObjects: Boolean);

Use this one to specify if you want the list to own its content (means: it takes care of destroying an item when it is removed from the list or the list is destroyed) or not. The constructor without parameter (which you probably used) sets this to true.

You probably just want a list like TList but for storing objects. If that's the case then create your list like this:

Allocations:= TObjectList.Create(False);

But if you want the auto-destruction behavior then just remove the for-loop. The object list will destroy your TXX_ALOC objects.

like image 103
Heinrich Ulbricht Avatar answered Dec 10 '22 23:12

Heinrich Ulbricht