[fpc-pascal] How are Assigned, Free, Nil and Destroy related?
Michael Müller
mueller_michael at alice-dsl.net
Sat Oct 22 09:53:23 CEST 2011
Am 22.10.2011 um 09:08 schrieb Frank Church:
>
>
> On 22 October 2011 07:20, Felipe Monteiro de Carvalho <felipemonteiro.carvalho at gmail.com> wrote:
> I understand Assigned as being the same as <> nil, so Assigned(Object)
> = Object <> nil
>
> I vaguely remember that it could be safer in some corner case, but I
> don't remember ever meting that.
>
> Free is how you release the memory allocated for a object. Free calls
> Destroy. Never call Destroy manually. When you implement the
> destructor you always implement Destroy, never change Free.
>
> Nil is not a routine, it is a value, it means that the object is
> empty, it does not exist / is not allocated. Nil in existing
> implementations that I know is represented by the value zero.
>
> The typical life-cycle of a object is:
>
> MyObject := TMyObject.Create;
> try
> MyObject.DoSomething();
> finally
> MyObject.Free;
> end;
>
> To implement this object you should implement Create, DoSomething and Destroy.
>
> --
> Felipe Monteiro de Carvalho
> _______________________________________________
> fpc-pascal maillist - fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
> This code is the source of my woes. SCStrings and FBreakStrings are part of an object. They are repeatedly used in a loop and I need to free the memory after the loop runs or free the space taken up by their strings
>
> type
> TRuntimeMonitor = class(TThread)
> private
> Frequency: Integer;
> IniFile: TMemIniFile;
> SCStrings: TStringList;
> FBreakStrings: TStringList;
> procedure DispatchOutput;
> procedure DisplayRawOutput;
> protected
> procedure Execute; override;
> public
> constructor Create(CreateSuspended: Boolean);
> end;
>
> procedure InitVars;
> begin
> if not Assigned(SCStrings) then
> SCStrings := TStringList.Create;
> if not Assigned(FBreakStrings) then
> FBreakStrings := TStringList.Create;
>
> IniFile := TMemIniFile.Create('zxtyu');
> end;
>
>
> procedure FreeVars;
> begin
> IniFile.Free;
> if Assigned(SCStrings) then
> SCStrings.Free;
> if Assigned(FBreakStrings) then
> FBreakStrings.Free;
> if Assigned(FBreakStrings) then
> debugln('FBreakStrings is still assigned');
>
> end;
>
>
> InitVars and FreeVars run in the Execute procedure of the thread
>
> When the loop runs again Assigned in InitVars is false so as soon as those FBreakStrings and SCStrings are accessed within the loop a SIGSEGV occurs. So what I want to know is whether Assigned remains true when Free is executed.
>
> In the mean time instead of using Free in FreeVars I will set the text property to the blank string to release the memory used by the strings.
In TRuntimeMonitor.Create() you should add
SCStrings := nil;
FBreakStrings := nil;
and in FreeVars() you should replace
if Assigned(SCStrings) then
SCStrings.Free;
if Assigned(FBreakStrings) then
FBreakStrings.Free;
by
FreeAndNil(SCStrings);
FreeAndNil(FBreakStrings);
You should also add a Destroy() with the FreeAndNil() lines to ensure that everything will be destroyed when freeing TRuntimeMonitor even if FreeVars() were not called or didn't finish 100% for what ever reason.
FreeAndNil() is one important function that was missing in your list. ;-)
FreeAndNil(Object) does
if Assigned(Object) then begin
Object.Free;
Object := nil;
end;
For locale objects Felipes example should be used.
Regards
Michael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20111022/167b20d0/attachment.html>
More information about the fpc-pascal
mailing list