[fpc-pascal] why dynamic array created in constructor not automatically free in destructor
Michael Van Canneyt
michael at freepascal.org
Thu Aug 7 11:32:18 CEST 2014
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.
More information about the fpc-pascal
mailing list