wowwwwwwww theo.......
your explaination was greate
Thanks for nice explaination.
Iqbal


--- In [email protected], Theodoros Bebekis 
<[EMAIL PROTECTED]> wrote:
>
> O/H Andries Bos Ýãñáøå:
> > 
> > 
> > Hello
> > 
> > What are the do and donn't when passing Lists from one procedure 
to another.
> > 
> > I do have three different procedures:
> > 
> > ProcedureOne;
> > var
> > LStringlist : TStringlist;
> > begin
> > LStringlist : TStringlist.create;
> > 
> > LStringlist.add....
> > 
> > procedureTwo(Lstringlist);
> > 
> > if LStringlist <> nil then
> > LStringlist.free;
> > end;
> > 
> > procedureTwo(AStringList : TStringlist = nil);
> > var
> > lStringlist : TStringlist;
> > begin
> > if AStringlist = nil then
> > lStringlist := TStringlist.create
> > else
> > lStringlist = AStringlist;
> > 
> > //do something
> > 
> > LStringlist.free;
> > end;
> > 
> > ProcedureThree
> > begin
> > proceduretwo;
> > end
> > 
> > I had an AV problem when freeeing the LStringlist in 
procedureOne. This 
> > was because it's already been freed in ProcedureTwo.
> > However where and when should the lStringlist in each procedure 
be freed?
> > ( I thought that after lStringlist = AStringlist in procedureTwo 
and the 
> > LStringlist.free the original LStringlist in ProcedureOne would 
also 
> > have been freed; Debugging shows that this is not true. )
> > 
> > I hope your answers would help me understand how and when a 
parameter 
> > may and should be freed.
> > 
> > Regards
> > 
> > Andries
> 
> 
> Andries
> 
> Objects are pointers.
> (we just don't need to use the de-referencing operator ^
>   with them).
> 
> Pointers point to a memory block or nowhere (=nil).
> So, objects point to a memory block or nowhere (=nil).
> 
> The memory block (read object), sometimes called memory object,
> exists in memory. Just once.
> 
> You may have a variable pointing to that
> memory block (read object).
> 
> var
>    B : TButton;
> begin
>    B := TButton.Create(nil);
> 
>    // more code here
> end;
> 
> You may have _more_than_a_single variable
> pointing to that very same memory block;
> 
> var
>    A, B: TButton;
> begin
>    A := TButton.Create(nil);
>    B := A;
> 
>    // more code here
> end;
> 
> When the above is true, and it happens very frequently,
> then the programmer has to be extremely carefull
> and, somehow, nilify ALL those variables
> when that memory block, they all point to, is freed (destroyed).
> Otherwise, a trouble is near.
> 
> var
>    A, B: TButton;
> begin
>    A := TButton.Create(nil);
>    B := A;
> 
>    B.Free;
>    A.Click; // oups
> end;
> 
> The GENERAL roule is: code that allocates a memory block
> is responsible for that memory block de-allocation.
> That is: a function/procedure/method that creates an object
> is responsible for freeing it.
> 
> Regarding parameters that are objects,
> (parameters are variables local to a function)
> here is an example which applies that rule.
> 
> procedure ListService(List: TStrings);
> begin
>    // 1. assume the List is created
>    // 2. do something with the List
>    // 3. do NOT destroy the List
> end;
> 
> var
>    List : TStringList;
> begin
>    List := TStringList.Create;
>    try
>      ListService(List);
>    finally
>      List.Free;
>    end;
> end;
> 
> Here is a very common situation.
> 
> procedure ClearList(List: TStrings);
> var
>    i : integer;
> begin
>    for i := 0 to List.Count - 1 do
>      if List.Objects[i] <> nil then
>        List.Objects[i].Free;
>    List.Clear;
> end;
> 
> 
> Of course there are exceptions to that
> memory block responsibility rule.
> But, as always, we should have a very good reason
> for breaking a rule.
> 
> One, the most frequent, exception says:
> "the callee creates the object
>   but the caller is responsible for freeing it"
> 
> An example that breaks
> the memory block responsibility rule.
> 
> function  Split(S: string; Delim: Char): TStrings; // caller must 
dispose Result
> beging
>    Result := TStringList.Create;
>    // split S based on Delim
>    // and Add() to Result
> end;
> 
> 
> var
>    S : string;
>    List : TStrings;
> begin
>    S := 'Provider=OLEDB4;Data source=C:\Data.MDB';
> 
>    List := Split(S, ';');
>    try
>      //do something with the List
>    finally
>      List.Free;
>    end;
> end;
> 
> Regarding functions that return an object
> that must be freed by the caller,
> here is a very common situation.
> 
> function Select(const SQL: string): TDataset;
> begin
>    Result := TSomeQueryClass.Create(nil);
>    // setup Result, giving it a TConnection etc
>    Result.SQL.Text := SQL;
>    Result.Active := True;
> end;
> 
> 
> An object parameter may also be passed by reference,
> that is as var or out (online help denotes the difference).
> By reference means that "I pass _the_address_of_ my variable
> and, please, make my variable point to where it should point".
> 
> procedure GetList(var List: TStrings);
> begin
>    if IsMonday then
>      List := MondayComboBox.Items
>    else
>      List := SaturdayComboBox.Items;
> end;
> 
> (
>    ...the above as function
> 
> function GetList: TStrings;
> begin
>    if IsMonday then
>      Result := MondayComboBox.Items
>    else
>      Result := SaturdayComboBox.Items;
> end;
> 
> and a function that utilizes an _untyped_ out parameter
> to return an object
> 
> function  Find(List: TComponentList; const Name: string; out Obj): 
Boolean;
> var
>    i : Integer;
> begin
>    Result := False;
>    for i := 0 to List.Count - 1 do
>      if AnsiSameText(Name, List[i].Name) then
>      begin
>        TComponent(Obj) := List[i];
>        Result := True;
>        Exit;
>      end;
> end;
> 
> )
> 
> 
> Well, who is responsible for freeing that
> resulting List or object? (lol).
> 
> Well, it depends on the situation, as always.
> And its a good habit to document all those,
> and similar functions,
> providing instructions to its user.
> 
> 
> 
> 
> -- 
> Regards
> Theo
> 
> ------------------------
> Theo Bebekis
> Thessaloniki, Greece
> ------------------------
> Greek_Delphi_Prog : a Delphi Programming mailing list in Greek at
>     http://groups.yahoo.com/group/Greek_Delphi_Prog
> 
> CSharpDotNetGreek : A C# and .Net mailing list in Greek language at
>     http://groups.yahoo.com/group/CSharpDotNetGreek
> 
> atla_custom : a Unisoft Atlantis Customization mailing list at
>     http://groups.yahoo.com/group/atla_custom
> ------------------------
>


Reply via email to