Solved

What's the best way of doing this?

Posted on 2002-05-30
15
239 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
[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
  • 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
Industry Leaders: 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 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
 

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

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!

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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

690 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