On Thu, 7 Aug 2014, Jürgen Hestermann wrote:

Am 2014-08-07 10:21, schrieb Dennis Poon:
TMyClass=class
public
  ar : array of integer;
  constructor Create;
 destructor destroy;override;
end;
TMyClass.Create;
begin
   inherited;
   SetLength(ar, 100);
end;
TMyClass.Destroy;
begin
   ar := nil;//<--- this is needed otherwise a memory leak is reported!
  inherited;
end;
I would expect the compiler would automatically insert this ar := nil on my
behalf because it seems like it does it for strings.
Am I missing some compiler directives?


I think strings are a very special case because they are treated diffently in many cases. Strings can be freed without harm because they are well defined and no parts of them point to other objects on the heap. They have a reference counter where the compiler logs how many instances are pointing to the string and only removes it when it has
reached zero.

If you have a dynamic array then elements may point to other structures (which again
may point to a structure that....) which again need to be freed.
If you have allocated memory yourself then the compiler does not know
how (and when) to free these objects. They may be used in other arrays or elsewhere.

The compiler frees dynamic arrays.

The following program:

Type
 TMyClass=class
 public
   ar : array of integer;
   constructor Create;
  destructor destroy;override;
 end;
 Constructor TMyClass.Create;
 begin
    inherited;
    SetLength(ar, 100);
 end;
Destructor TMyClass.Destroy;
 begin
//    ar := nil;//<--- this is needed otherwise a memory leak is reported!
   inherited;
 end;


begin
  With TMyClass.Create do
    Free;
end.

Reports 2 allocated blocks, and 2 free blocks. Exactly as you would expect:
home: >fpc -S2 -gh ta.pp
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
home: >./ta
Heap dump by heaptrc unit
2 memory blocks allocated : 432/432
2 memory blocks freed     : 432/432
0 unfreed memory blocks : 0
True heap size : 294912
True free heap : 294912


What can happen is that you did somewhere a
  B:=MyClass.ar;

and as long as B is in scope, the reference count of A is not 0 when the object 
is freed, and the array is also not freed.
(the ar:=nil will not change that)

Another possibility is a forgotten 'inherited' somewhere in a destructor.

Michael.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to