Solved

What's the best way of doing this?

Posted on 2002-05-30
15
233 Views
Last Modified: 2010-04-04
We have some old code which is possibly causing us headache.  We keep getting access violations all the time, and I can't work out where the problem starts.

The person who originally wrote the code did things a little differently to what I'm used to, and I'm trying to work out if this is OK or not.

The form is dynamically created:

MktForm := MktForm.Create(Self);
MktForm.ShowModal;

in MktForm, this is done:

FormClose
  Action := caFree;

FormDestroy
  MktForm := nil;

Is this OK to do?  Is instructing the Action to free the form on close, plus setting it to Nil in the FormDestroy allowed?

I can't trace the source to where the A/V occurs.  It's annoying the hell out of me.  It only happens sometimes (when a certain sequence of clicks is made).  So I'm trying to find all dynamically created objects and make sure they're all freed.  There are a lot of them, but the majority aren't called in most circumstances so it's not causing my general problem.

Any help would be appreciated.

Stu
0
Comment
Question by:Stuart_Johnson
  • 3
  • 2
  • 2
  • +6
15 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7043859
the nil in formdestroy is not a good choice
0
 
LVL 7

Expert Comment

by:Motaz
ID: 7043923
When you create any component at run-time and you assign an owner for it, the owner (Form for example) will destroy it when the owner destroyed, so that if the owner find that this component is already destroyed or assigned to nil, an access violation some times occure.

until now, I didn't find a solution for this problem, so that I lave such components without destorying and let thier owner to destroy it.

Motaz
0
 
LVL 9

Expert Comment

by:ITugay
ID: 7043973
my usual way:

  MktForm := MktForm.Create(nil);
  try
    if MktForm.ShowModal = mrOK then
    begin
       // do something here
    end;
  finally
   MktForm.Release;
   // if you have to access MktForm variable from another part of your application
   // and be sure that it is initialized or not (checking nil) then
   // uncomment line bellow
   // MktForm := nil;
  end;

------
Igor.


0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 7044097
with MktForm.Create(Self) do
  try
    if ShowModal = mrOK then
    begin
       // do something here
    end;
  finally
    Free;
  end;

That is my way of doing it.
I also delete the global variable from MktForm.
I never had a problem with Free for the form.
0
 
LVL 9

Expert Comment

by:ITugay
ID: 7044115

>> MktForm := MktForm.Create(nil);
must be:
MktForm := TMktForm.Create(nil);

 >> with MktForm.Create(Self) do
the same error
with TMktForm.Create(Self) do

btw, Release is preferable. I had problems with Free and it was solved regarding Release.


----
Igor
0
 
LVL 14

Accepted Solution

by:
AvonWyss earned 100 total points
ID: 7044367
I don't think that the problem is with the form stuff. I'd suggest that you get yourself the free debugging tool MemProof from here:
http://www.automatedqa.com/products/memproof.asp

It will keep track of memory which is being freed more than once, overwritten, and stuff like that. Has helped me often to find different AV problems.
0
 
LVL 7

Expert Comment

by:Motaz
ID: 7046475
Robert, free problem is not always occured, I use it for long time in my graduation project while I was developing it, and every thing working fine, in the discussion day it rais access violation when I close my project, and that was the first time, so that you can not be sure if freeing owned component manually safe or not.

Motaz
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Expert Comment

by:Coltrui
ID: 7046509
I've experienced the same problems and this worked for me:

1. Change the 'Self' into 'Application'
2. Make sure that every form is in the 'available form'-section instead of the 'autocreate form'-section.

0
 
LVL 3

Expert Comment

by:oraelbis
ID: 7047160
There is some code from my program:

type
  TfrmMinCost = class(TForm)
    . . .
  private
    . . .
  public
    . . .
  end;

procedure ShowMinCostForm;

var
  frmMinCost: TfrmMinCost;

implementation

{$R *.DFM}

procedure ShowMinCostForm;
begin
 try
   if not Assigned(frmMinCost) then
     Application.CreateForm(TfrmMinCost,frmMinCost);
   if frmMinCost.ShowModal = mrOK then
    begin
      . . .
    end;
 finally
   frmMinCost.Free;
   frmMinCost:=nil;
 end;
end;
    . . .

end.


Remove this form from Project->Options->Forms Auto-create list.
0
 
LVL 1

Expert Comment

by:thegroup
ID: 7047446
In my experience you could set the OnCreate event handler to:

Action = caFree;

This makes the memory being freed without problems.
0
 
LVL 3

Expert Comment

by:oraelbis
ID: 7051043
Check your modules for not disconnecting connections, such as Socket, HTTP or data access components.
Close all DataSets, before closing forms or application.
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7053399
Hi Folks,

Sorry for the length of time it's taken for me to post anything.  All your comments are great and very helpful.  Most of what you have said I already do - remember the code I posted above was someone elses.

What I usually do is never have any forms auto created (except the main form).  I then create the forms, but I always use nil as the  owner - unless the form is an MDI child.  I always free the form using FormName.Free:

  MyForm := TMyForm.Create(nil);
  try
    MyForm.ShowModal;
  finally
    MyForm.Free;
  end;

I never have problems with it.

I just wanted clarification that what was done above wasn't really advisable.  The guy who coded our app originally was a dreadful programmer.  His code is the worst I've seen (even our 1st year juniors code better than him).

I'll have a good read through what's posted in the morning (as it's fairly late here now and I want to get home).  I'll ask for more info if I need it, or award some points.

Thanks again,


Stu
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7061170
Meikl,

You said "the nil in formdestroy is not a good choice".  

Can you tell me why?

Our app is MDI.  We check to see what forms are opened using if FormName <> nil then do....

If we don't say FormName := nil; in the FormDestroy, FormName is always assigned "something", so testing for nil doesn't work.

AvonWyss:

I love that memory checking utility!  Thanks for the link.

thegroup:

AFAIK FormCreate doesn't have an action property, but FormClose does.

oraelbis:

All datasets are closed before the form is closed.  We don't have anything else which could cause problems that we know of (no socket components or stuff expecting data).

Although AvonWyss didn't directly answer the question, he did give me some great tips and a very useful application.  The points are yours.

Thanks to everyone for your help and input.  I really appreciate it.

Stu
0
 
LVL 14

Expert Comment

by:AvonWyss
ID: 7061229
Stuart, thank you!  Have a nice weekend.
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7061240
No problems at all!  You have a great weekend too!

Stu
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

747 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now