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