Re: Create and free Delphi form dynamically

Posted by webmaster Guido

In Reply to Create Delphi form dynamically posted by Johan

: When I create a Delphi form dynamically, the constructor "Create" expects an "Owner" parameter. : When should I specify "nil", "self" or "Application", and why?

When creating a Delphi component dynamically (a form or whatever other component), in the Create method you have to specify its owner, for example:

  Form2 := TForm2.Create(aOwner);

aOwner can be another object or nil (no owner):

- a component with an owner is destroyed automatically, when its owner is destroyed.

- a component without an owner (you passed nil as the owner) will not be destroyed automatically, so you must destroy (free) it yourself. Failing to do so leads to what is called "memory leaks", that eventually could "hang" your program or even need a reboot of Windows.

Here are a few practical rules:

  • If you dynamically create Form2 in the code of your main form Form1, and you want Form2 to be destroyed automatically at the end of the program, then pass Application as the owner.
     
  • If you create Form3 in the code of another form Form2 (not the main form), and you want Form3 to be destroyed automatically when Form2 is destroyed, then pass self as the owner. The variable self in this case points to Form2.
     
  • If you dynamically create a form (or any other component) and for some reason you want to explicitly free it sometime later, always pass nil as its owner. Otherwise, you run the risk that the component is "freed" twice, giving errors that are very difficult to debug.

Now, for some code examples.

1. Owner is another form
var
  Form2: TForm2;
 
procedure TForm1...  
begin
  ...
  Form2 := TForm2.Create(Form1);

Form2 will be destroyed automatically when Form1 is destroyed. DO NOT "Free" Form2 yourself !

Instead of TForm2.Create(Form1) you will usually see:

var
  Form2: TForm2;
 
procedure TForm1.SomeProcedure; 
begin
  ...
  Form2 := TForm2.Create(self); 

The variable self is the object of which SomeProcedure is a method. That's a complicated way of saying: in our example, self is the same as Form1. Thus, the two code examples above are equivalent.

2. Owner is the global variable Application
var
  Form2: TForm2;
 
procedure TForm1...  
begin
  ...
  Form2 := TForm2.Create(Application);

Here, Form2 will be destroyed automatically when the Application is destroyed, that is: when the program stops.

3. Owner is nil
procedure TForm1.SomeProcedure;
var
  FDialog: TForm2;
begin
  FDialog := TForm2.Create(nil);
  FDialog.ShowModal;
  ...
  FDialog.Free;

In this case, the form FDialog does not have an owner, so you have to destroy FDialog yourself from the moment that it's not needed anymore.

Guido, DelphiLand Team