[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