Solved

Freeing form - variables not freed ?

Posted on 1998-10-25
11
306 Views
Last Modified: 2010-04-06
In my program, forms are created and destroyed. I was surprise to see that when freeing a form then recreating it variables and constants retain the value they had when the form was freed. I don't want this. I can I really free the memory ?
0
Comment
Question by:moonrise
11 Comments
 
LVL 17

Expert Comment

by:inthe
ID: 1344378
Hello MoonRise,
perhaps you need to use the freemem procedure look it up under delphi help it has an example  
  ¤¤¤¤¤¤¤InThe¤¤¤¤¤¤¤
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1344379
Hello Guys...

The memory is not free immediately as you free the form... Sometimes it frees as you close down the up... I'm not sure about that though, but I'm sure it doesn't free it immediatelly...

What do you think is going to happen if you do this??

Form1.Free;
Form1 := nil;

Try this one... Cheers,
Viktor
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1344380
What variables? The form's private/public/protected, or others?
0
ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

 
LVL 12

Expert Comment

by:rwilson032697
ID: 1344381
Remember, as a general rule, always use Form.Release instead of Form.Free to destroy a form (if you are doing it directly and not via Action := caFree in the FormClose event).

Release kills a form gracefully, allowing all pending messages to be processed before the form is destroyed. Free just nukes it - if there are pending messages you are introuble.

Perhaps you could post a code sample of where you destroy and recreate the form, and an indication of what variables retain their values...

Cheers,

Raymond.
0
 
LVL 1

Expert Comment

by:Gerhard100198
ID: 1344382
I quote from the D4 help files (TObject.Free):

"If you want to free the form, call the Release method, which destroys the form and releases the memory allocated for it after all its event handlers and those of the components it contains are through executing."


and from TCustomForm.Release:

procedure Release;

Description

Use Release to destroy the form and free its associated memory.

"Release is much like the Free method except that Release does not destroy the form until all event handlers of the form and event handlers of components on the form have finished executing. Any event handlers of the form should use Release instead of Free. Failing to do so could lead to an access violation."

If have also read on verious occasions that freeing the form does not "clear" the memory used by the form.

We ran into a problem with the following code a wile back:

Form1.Free;
If Form1 = Nil then Form1.Create(Self);
Form1.Caption := 'Test';

We would get an access violation on the last line. After reading up on this I found that a lot of people had exactly the same type of problem. The answer seemed to be to manually  set the pointer  to Nil. We changed the code in our test procedure above to read:

Form1.Free;
Form1 := Nil;
If Form1 = Nil then Form1.Create(Self);
Form1.Caption := 'Test';

The code now worked fine.

BTW We tried Form1.Assigned as a test instead of Form = Nil and received exactly the same error.

Gerhard
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1344383
Gerhard, there is a serious mistake in your sources!!!

"Form1.Create(Self);" is absolute wrong!!! Since you call a method of the form you freed just one line ago. This method "Create" is no longer valid!
(1) You HAVE to use the class method ("TForm1.Create").
(2) You HAVE to handle the result of the Create method ("form1:=TForm1.Create(Application)").

If your code does not end in an Access Violation, it's just luck!

Regards, Madshi.
0
 

Author Comment

by:moonrise
ID: 1344384
Maybe my question was not clear enough. Anyway I solved my problem by replacing the constants with global variables which I reset in the OnDestroy event of the form.

I experimented with Release instead of Free. Not only does it not reset the variables/constants but it also crashes my program.

Thank you all.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1344385
Probably you've solved it but what you could have done wrong is this...

var
  Btn : TButton;
begin
  Btn := TButton.Create(self);
  //some properties... you don't free this object...
  Btn := TButton.Create(self);
  /Other properties...
Now the old button is still there and can't be disposed because the Btn variable pointed at the address of the first one created/....and now it points at the second one so your first button is somewhere in memory and won't be freed until you don't reboot your PC...
end;

I know you are working with Forms and not Buttons but it is the same thing for all controls... Hope this helps a bit!

Cheers,
Viktor
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1344386
moonrise,

please give us a little example project that crashes (or that does not free the variables), and I'm sure we all will find the bug together...

Regards, Madshi.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1344387
yup, Madshi is completely right :)
0
 

Accepted Solution

by:
endro earned 100 total points
ID: 1344388
Here are some suggestions:
1. When creating the form, just re-initialize those variables in the top of codes.
2. Try to put this code on OnClose event of the form:
  Action := caFree;

Hope this helps you.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

803 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