?
Solved

Resource Leak on Form create

Posted on 2003-10-27
16
Medium Priority
?
615 Views
Last Modified: 2010-04-05
Hi, I am using BoundsChecker to detect leaks using Delphi 5.  When I call a modal form, it reports resource leak on inherited Create (owner) line, even though I have tried to call create with different ways, and I even removed the constructor method, and instead put the code in form.Create, but it is still reporting leak.  Amazingly, boundschecker does not report leak in some other modal forms with create or without create constructor.  I must have to remove this leakage.  I am not creating any object like TStringList in constructor.  I will really appreciate your help.  The sample code is as below in which leak reported:

procedure TfrmAR.BitBtn2Click(Sender: TObject);
var
   f: TfsARMST;
   CustNo,CustName: String;
begin
   inherited;
   try
     f := TfsARMST.Create(Self, CustNo, CustName); //<--BoundsChecker shows leak here if no constructor defined.
     if f.Showmodal = mrOK then
          Edit1.Text := CustNo;
   finally
     f.Free;
   end;
end;

//-----------
unit sARMST
. . .
 private
    { Private declarations }
    ReturnValue1 : ^string;
    ReturnValue2: ^String;
    procedure CreateQuery;
  public
    constructor Create(AOwner:TComponent; var Value1:string; Var Value2: String);
  end;

constructor TfsARMST.Create(AOwner:TComponent; var Value1:string; Var Value2:string);
begin
 inherited Create(AOwner);  //<<----BoundsChecker shows leak here if constructor defined.

 Query1.Databasename:= FSDataModule.FSDMDb.DatabaseName;
 ReturnValue1 := @Value1;
 ReturnValue2 := @Value2;
 ComboBox1.ItemIndex := 0;
 EFind.Text := Value1;
 CreateQuery;
end;

procedure TfsARMST.CreateQuery;
Var
   ACN: String;
begin
  with Query1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('Select AR_KY_MST_ACN, ');
    SQL.Add('      AR_FD_MST_NAME, ');
    SQL.Add('      AR_FD_MST_TEL_NO, ');
    SQL.Add('      AR_KY_MST_SNM, ');
    SQL.Add('      AR_FD_MST_CITY,');
    SQL.Add('      AR_FD_MST_STATE ');
    SQL.Add('FROM AR_DS_MST_R ');
   
    if  ComboBox1.ItemIndex=1 then
    begin
        SQL.Add('WHERE AR_KY_MST_ACN Like :ACN' );
        ParamByName('ACN').AsString := EFind.Text+'%';
        if RGSortOrder.ItemIndex=0 then
            SQL.Add(' ORDER BY AR_KY_MST_ACN ASC')
        else
            SQL.Add(' ORDER BY AR_KY_MST_ACN DESC');
    end;
 end;
end;

Thanks

0
Comment
Question by:mimran
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
  • 3
  • +1
16 Comments
 

Expert Comment

by:PGKalle
ID: 9630498
I can only describe a related problem appearing in Delphi 5: Within a ShowModal-constructed Form you sometimes have (very strange and from system to system different (!!)) compiler errors. Perhaps it is a compiler bug still not fixed.

What I did (after a long period of discussions with friends and some computer sciences students): I did not directly call commands concerning objects which are subclasses of the new created one (= the ShowModal Form) in the Creator- as well as in the OnCreate-procedures.
The alternative: all initializing commands concerning objects of your ShowModal-Form are e.g. called the first time when called OnPaint of your Form, afterwards the command execution is blocked by a global (boolean) flag. Then you have the check if the boolean flag is still active every time you repaint your Form, but that should be a no problem viewed from the perspective of calculation time complexity.

Perhaps you try this (very unusual, I agree) possibility. If it works without any mistakes then, we could consider contacting Borland for a bugfix. If you really have the same problems I had with my last project, that surely is a compiler bug.

Kalle
0
 

Author Comment

by:mimran
ID: 9630572
Hi Kalle,

Thanks for yr suggestion.  Before testing yr suggetion, I did one thing.  I am neither creating any contructor method nor initializing anything in form.onCreate event.  So I am just creating and opening like a simple form like:

try
   f := TfsARMST.Create(Self);
   f.showmodal;
finally
   f.Free;
end;

Boundschecker is reporting resource leak on Create (Self).  I don't know what's happening, but I will test your suggesting and let's see..:)

0
 

Expert Comment

by:PGKalle
ID: 9630652
Hm,

funny thing. ;-)
Is your Form declared to be not auto-generated [=static] by program startup? Normally this simple thing you did now should work...
Or what if you use "Application" instead of "Self" as the owner?

Kalle
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:swift99
ID: 9631380
The memory leak is from the string handling code.

 ReturnValue1 := @Value1;
 ReturnValue2 := @Value2;

It is odd, but Delphi copies Value1 and Value2, then assigns the addresses of the copies to the ReturnValue variables.

I learned of this recently from another question on EE, and it immediately predicted/explained a number of memory leak situations to me.

Also, in this case, the strings being passed are owned by an unknown scope.  So far as the "Create" method is converned, the strings may be deallocated at any time by the proper scope owner.

Rather than making the ReturnValue's ^String, I would recommend just making them String so that their scope is known (the current object) and Delphi's transparent memory management for strings can function without side effects.

This is the price paid for the nearly automatic string handling that we take for granted today.  We really need to pay atention to the details of the memory management scheme or we get bit.
0
 

Author Comment

by:mimran
ID: 9634952
Auto generate (Autocreate) form is unchecked.
I want to draw yr main attention the same problem with its parent form.  Actually, the following line creates a dialog box as a 'lookup' to select a value from, and pastes the value on actual or parent form.

f := TfsARMST.Create(Self, CustNo, CustName);

I can fix this leak by replacing with my own created 'lookup' which is not leaking any resources, but there is resource leak in parent form on create method which I am more concerned of.  

procedure TfFMAR37.BitBtn2Click(Sender: TObject);  //Calling parent form from menu
var
   f: TfFMAR37A;  //Parent form
begin
   inherited;
   try
     f := TfFMAR37A.Create(Self);  //<-- BoundsChecker shows leak here if I remove constructor method from parent form.
     f.Showmodal;
   finally
     f.Free;
   end;
end;

//-- Parent form constructor method...
constructor TfFMAR37A.Create(AOwner: TComponent);
var
   Size: Cardinal;
   User: array[0..20] of Char;
   c4 : integer ;
begin
   inherited Create(AOwner);  //<-- BoundsChecker shows leak here if delphi calls parent's constructor method.

   with StringGrid1 do
   begin
      Cells[0, 0] := 'Ref. #';       Cells[2, 0] := 'Amt Left';
      Cells[1, 0] := 'Org Amt';      Cells[3, 0] := 'Date';
   end;

   with StringGrid2 do
   begin
      Cells[0, 0] := 'Ship To';
      Cells[1, 0]  := 'Inv. #';         Cells[2, 0] := 'Inv. Date';
      Cells[3, 0] := 'Desc';           Cells[4, 0] := 'Amount';
   end;

// Get User ID
   Size := 20;
   GetUserName(User, Size);
   Label9.Caption := Uppercase(Copy(User, 1, 20));
end;

This is how other forms are created, but boundschecker is showing resource leak in some forms, not all of them.  BoundsChecker is also showing lots of leak in Controls.pas library at SetProp function.  I don't know what the heck it is and how to fix.  

I don't if this is a bug, but the application sometimes crash with 'system out of resources'.  

Thanks for your any advice in advance.
0
 
LVL 6

Expert Comment

by:swift99
ID: 9635062
It sounds like it is time to upgrade to D7.
0
 

Expert Comment

by:PGKalle
ID: 9638309
Bad thing. Wonder what "out of recources" means...

Perhaps the algorithm really addresses another dynamically (not already existing) form as the owner and there is an internal invalid pointer operation (expected goal but found "nil" or so on).

The only thing I can suggest: Test it with different owners of the new created Form (e.g. "Application" or even a new custom (dummy) parent). So you should eliminate all eventualities concerning bad parent references.

If that doesn't work, I say it's one of Borlands problems. As said, I also had many problems with dynamically generated Forms - perhaps that is a product area not so much used and thus not well enough financed in development.

Kalle
0
 
LVL 6

Expert Comment

by:swift99
ID: 9639043
Our Of Resources could mean kernel handles, memory, file handles, or any other resource.  You need to get more detailed information.

I have had no problems with dynamically creating forms, apart from the initial conceptual gap.  In reality, all forms are created dynamically.  You can even visit the code in your application.
0
 

Author Comment

by:mimran
ID: 9642914
I appreciate yr time spent to answer.

hmm..It sounds like problem is in Delphi.  

How can I create my own dynamic parent instead of 'self' for creating form?  I tried with 'Application' before, but did not work.  Memproof is showing unfreed resources by Kernel32.dll, MFC42.dll, and in unit sysinit.pas and system.pas.

Can you help me solve:
* BoundsChecker is showing 16 byte memory leak in Sysinit.pas delphi library in "InitThreadTLS" procedure at p := LocalAlloc(LMEM_ZEROINIT, Longint(@TlsLast));

* In Registry.pas, Stack memory overrun error, copying 4 bytes to Info.RegData starting offset.....(need to increase stack size or something?)

* Many Resource leaks in controls.pas library allocated by SetpropA function.  I don't know how to fix this leaks.

Thanks. I appreciate your reply.
0
 
LVL 6

Expert Comment

by:swift99
ID: 9642996
you can use NIL for the owner, but then you need to manage freeing the form yourself on application close.

Stack over run error is usually due to recursion.  You probably have an event loop or tail recusrion error

resource leaks in controls.pas - sounds like it is time to upgrade to D7 or D8.
0
 
LVL 6

Expert Comment

by:swift99
ID: 9643117
And Delphi 6 was well known as a buggy release - I never used it because we went straight to 6.
0
 
LVL 6

Accepted Solution

by:
swift99 earned 750 total points
ID: 9643122
Delphi 5 was a buggy release (aargh!  not enough caffeinne!  Caffeinne!)
0
 

Author Comment

by:mimran
ID: 9645886
hi everyone, thanks for your comments.

Now, I compiled the application in Delphi 7, In order to test in debugging tool, I have memory Sleuth 3 downloaded trial version, I think it supports delphi 7 but I don't have unlock key!  Turbopower is not in the bussiness anymore, so would anyone like to share the key with me, if it is not legal to do so??

Thanks.
0
 

Author Comment

by:mimran
ID: 9658699
you all gave me valuable suggestions, I appreciate you all.  
I think, finally all I have to check leak in delphi 7, so I need memory sleuth 3 unlock key.
I am wondering, if anyone can share the key...
Thanks you all again..
0
 

Author Comment

by:mimran
ID: 9704243
It seems like it is delphi 5 library leaking.  So far I have fixed few leaks inside my application, not delphi lib.  
I accept swift99 answer.
Thanks everyone.
0
 

Expert Comment

by:DirkVerdonck
ID: 14722647
question from mimran:  what version of boundschecker are you using?  I used to work with Boundschecker back when I Was still programming in delphi 3.  It worked great and I was very happy with it.  But now I'm using delphi 5 and I can't get Boundschecker to integrate with delphi.

So any info you could provide about what version of boundschecker does work with delphi 5 would be very helpful to me.

Thanks in advance.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses
Course of the Month14 days, 20 hours left to enroll

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question