🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
14 messages
14 total messages Started by Dan Mayo Thu, 18 Jan 2007 19:41
Creating new TForm causes 'Out of Resources' error on WinXP
#2727
Author: Dan Mayo
Date: Thu, 18 Jan 2007 19:41
20 lines
1553 bytes
Hi,

I have a fairly simple form that I dynamically create throughout a 
program I am working on.  However, every once in awhile the program 
crashes due to a 'Out of Resources' error (according to Windows) 
however, when I log the amount of memory in use and available; there is 
plenty of physical memory yet.  Using a tool to help discover where the 
code was dying, I found out it was on the 'new' call when I dynamically 
create the new form.  Shortly after creating the form and temporarily 
displaying some things I always close the form and then call the delete 
operator.

Why am I getting the "Out of Resources" error?  The form only contains 
a TButton, a TCaption, and a TProgressBar.

Ideas?

Thanks in advance!

Dan
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2728
Author: Remy Lebeau (TeamB)
Date: Thu, 18 Jan 2007 20:00
37 lines
2069 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message
news:45afcda9$1@newsgroups.borland.com...

> I have a fairly simple form that I dynamically create throughout a
> program I am working on.  However, every once in awhile the
> program crashes due to a 'Out of Resources' error (according to
> Windows)

GDI resources are very limited.

> however, when I log the amount of memory in use and available;
> there is plenty of physical memory yet.

Available physical memory is different then available GDI resources.

> Using a tool to help discover where the code was dying, I found out
> it was on the 'new' call when I dynamically create the new form.
Shortly
> after creating the form and temporarily displaying some things I
always
> close the form and then call the delete operator.

Are you absolutely sure that 'delete' is always being called?  In any
case, how much UI resources are you already using before creating the
new form instance?

> Why am I getting the "Out of Resources" error?

Because you are running low on available resources ;-)

> The form only contains a TButton, a TCaption, and a TProgressBar.

But what does the rest of your UI contain?


Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2729
Author: Dan Mayo
Date: Thu, 18 Jan 2007 20:23
64 lines
3264 bytes
> GDI resources are very limited.
Ok; I'll google this one to get a better idea...


> Available physical memory is different then available GDI resources.
Perhaps google will be my friend here too. :)

> Are you absolutely sure that 'delete' is always being called?  In any
> case, how much UI resources are you already using before creating the
> new form instance?
YES  There is no other way for the code to exit from that function.

> But what does the rest of your UI contain?
My whole user interface has a number of other buttons, labels, graphs, 
etc.  The weird thing I don't understand is that I am basically in a loop:

Simplified code is as follows:

void MyClass::TheLoop()
{
   bool Stop = false;
   while (!Stop)
   {
      TCustomForm *theDialogThatCrashes;
      theDialogThatCrashes = new TCustomForm(this);  //<-- This is where 
the out of resources occurs
      theDialogThatCrashes->Visible = true;
      TriggerLongHardwareRelatedTask();
      bool DoingSomeLongHardwareRelatedTask = true;
      while (DoingSomeLongHardwareRelatedTask)
      {
         //update the progress bar
	if (theDialogThatCrashes->ProgressBar->Position > 
theDialogThatCrashes->ProgressBar->Max)
          {
              theDialogThatCrashes->ProgressBar->Position = 0;
	 }
         else
	{
           theDialogThatCrashes->ProgressBar->Position += 1;
         }
	DoingSomeLongHardwareRelatedTask = !HardwareTaskComplete();
         Application->ProcessMessages(); //call this so that Button 
event on theDialogThatCrashes is called; the button event sets that 
forms Stopped boolean value to true if it is pressed
         if (theDialogThatCrashes->Stopped)
         {
           DoingSomeLongHardwareRelatedTask = false;
           Stop = true;
	}
      }
      theDialogThatCrashes->Visible = false;
      delete theDialogThatCrashes;
   }
}


For simplicity, the hardware event is sending a message out of the 
serial port and waiting for the RXBuffer on taht serial port to reach a 
certain byte level.

I don't see why I'm running out of resources with the above code.

Any suggestions?
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2730
Author: Remy Lebeau (TeamB)
Date: Thu, 18 Jan 2007 21:41
70 lines
3199 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message
news:45afd751$1@newsgroups.borland.com...

> YES  There is no other way for the code to exit from that function.

What about if exceptions occur?  You are not protecting your code from
that scenerio at all.

> My whole user interface has a number of other buttons, labels,
graphs,
> etc.  The weird thing I don't understand is that I am basically in a
loop:

You don't need to re-create the form on each iteration of the loop.
You could create it once and then let the loop show/hide it as needed.

Try this instead:

    void MyClass::TheLoop()
    {
        TMyForm *theDialog = new TMyForm(NULL); // no Owner needed
        try
        {
            bool Stop = false;
            while( !Stop )
            {
                theDialog->ProgressBar->Position = 0;
                theDialog->ProgressBar->Max = ...;
                theDialog->Stopped = false;
                theDialog->Show();

                TriggerLongHardwareRelatedTask();

                bool DoingSomeLongHardwareRelatedTask = true;
                while( DoingSomeLongHardwareRelatedTask && !Stop )
                {
                    if( theDialog->ProgressBar->Position <
theDialog->ProgressBar->Max )
                        theDialog->ProgressBar->StepIt(); // Set the
Step property to 1
                    else
                        theDialog->ProgressBar->Position = 0;

                    DoingSomeLongHardwareRelatedTask =
!HardwareTaskComplete();

                    Application->ProcessMessages();
                    Stop = theDialog->Stopped;
                }

                theDialog->Hide();
            }
        }
        __finally
        {
            delete theDialogThatCrashes;
        }
    }


Now, with that said, you should seriously consider moving the hardware
code into a separate worker thread instead.  The thread can post
notifications about its status to the main thread to update the
dialog.  It is not good to perform lengthy operations in the main
thead, and call ProcessMessages() like that can introduce other subtle
problems elsewhere.


Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2731
Author: Dan Mayo
Date: Thu, 18 Jan 2007 22:13
89 lines
4261 bytes
Well, I did say it was a simplified version :)
I should have done a better job of writing the demo code.  The actual 
code is within a function that reads from the hardware and shows a 
progress bar basically indicating the timeout period.  The program 
crashes at random times of program execution after a random number of 
calls to this function.

I hear your point about threads.  I suppose I can look at that.

But back to the original point, I don't know why the error is occurring; 
I don't believe there are any other exit points or any exceptions thrown 
except out or system resources. I am using Eureka Log to track program 
execution and that's how I identified this spot; it doesn't show any 
other exceptions and PC-Lint doesn't report any errors in the code at all.



Remy Lebeau (TeamB) wrote:
> "Dan Mayo" <dmayo@dickey-john.com> wrote in message
> news:45afd751$1@newsgroups.borland.com...
> 
>> YES  There is no other way for the code to exit from that function.
> 
> What about if exceptions occur?  You are not protecting your code from
> that scenerio at all.
> 
>> My whole user interface has a number of other buttons, labels,
> graphs,
>> etc.  The weird thing I don't understand is that I am basically in a
> loop:
> 
> You don't need to re-create the form on each iteration of the loop.
> You could create it once and then let the loop show/hide it as needed.
> 
> Try this instead:
> 
>     void MyClass::TheLoop()
>     {
>         TMyForm *theDialog = new TMyForm(NULL); // no Owner needed
>         try
>         {
>             bool Stop = false;
>             while( !Stop )
>             {
>                 theDialog->ProgressBar->Position = 0;
>                 theDialog->ProgressBar->Max = ...;
>                 theDialog->Stopped = false;
>                 theDialog->Show();
> 
>                 TriggerLongHardwareRelatedTask();
> 
>                 bool DoingSomeLongHardwareRelatedTask = true;
>                 while( DoingSomeLongHardwareRelatedTask && !Stop )
>                 {
>                     if( theDialog->ProgressBar->Position <
> theDialog->ProgressBar->Max )
>                         theDialog->ProgressBar->StepIt(); // Set the
> Step property to 1
>                     else
>                         theDialog->ProgressBar->Position = 0;
> 
>                     DoingSomeLongHardwareRelatedTask =
> !HardwareTaskComplete();
> 
>                     Application->ProcessMessages();
>                     Stop = theDialog->Stopped;
>                 }
> 
>                 theDialog->Hide();
>             }
>         }
>         __finally
>         {
>             delete theDialogThatCrashes;
>         }
>     }
> 
> 
> Now, with that said, you should seriously consider moving the hardware
> code into a separate worker thread instead.  The thread can post
> notifications about its status to the main thread to update the
> dialog.  It is not good to perform lengthy operations in the main
> thead, and call ProcessMessages() like that can introduce other subtle
> problems elsewhere.
> 
> 
> Gambit
> 
> 
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2732
Author: David Pratt
Date: Fri, 19 Jan 2007 11:27
12 lines
1439 bytes
> void MyClass::TheLoop()
> {
>   bool Stop = false;
>   while (!Stop)
>   {
>      TCustomForm *theDialogThatCrashes;
>      theDialogThatCrashes = new TCustomForm(this);  //<-- This is where 
> the out of resources occurs

I don't know about subsequent versions, but Version 5 says do NOT create 
instances of TCustom form; Instantiate descendants of TCustomForm instead. 
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2733
Author: Bob Gonder
Date: Fri, 19 Jan 2007 13:25
7 lines
1507 bytes
Dan Mayo wrote:

>But back to the original point, I don't know why the error is occurring; 

Also note that there are other resources than GDI, such as various
handles. If you don't always close your handles, they can leak and run
you out of resources.
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2735
Author: Dan Mayo
Date: Fri, 19 Jan 2007 14:19
21 lines
1961 bytes
Bob Gonder wrote:
> Dan Mayo wrote:
> 
>> But back to the original point, I don't know why the error is occurring; 
> 
> Also note that there are other resources than GDI, such as various
> handles. If you don't always close your handles, they can leak and run
> you out of resources.
> 
> 

How can I track this bug down?

I am running the application with Task Manager open and I'm watching 
memory usage and #GDI Object.  My memory usage hovers around 12MB and 
the number of GDIs hovers around 180.  I can see the memory usage and 
GDI count go up as the program uses more and then right back down as 
objects are freed.  The memory doesn't climb out of control; nor does 
the GDI count.

Any ideas?
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2734
Author: Dan Mayo
Date: Fri, 19 Jan 2007 14:32
20 lines
2077 bytes
 From the help file:
"Note:	When working with form objects, do not explicitly call the Free 
or Destroy method to free them. Instead, use the Release method, which 
waits until all event handlers have finished executing."

Does this mean I should call "theDialog->Release();" rather than "delete 
theDialog;"?

Reading the "Release()" function call help the note appears 
contradictory to the TForm() section:

"Note:	Release returns immediately to the caller. It does not wait for 
the form to be freed before returning."

So does Release() wait for everything to be done first before returning 
to the next line in code?  Do I need to call both Release() and then 
delete?  Is there something I should do to make sure that Release() has 
finished prior to calling delete?

Dan
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2736
Author: Dan Mayo
Date: Fri, 19 Jan 2007 15:11
29 lines
2294 bytes
Is there anything wrong with doing destruction of a form like this?
theForm->Release();
Application->ProcessMessages();
//then go on my merry way... (I was noticing without ProcessMessages 
that theForm was still in memory..

Is there a better way?

Dan Mayo wrote:
>  From the help file:
> "Note:    When working with form objects, do not explicitly call the 
> Free or Destroy method to free them. Instead, use the Release method, 
> which waits until all event handlers have finished executing."
> 
> Does this mean I should call "theDialog->Release();" rather than "delete 
> theDialog;"?
> 
> Reading the "Release()" function call help the note appears 
> contradictory to the TForm() section:
> 
> "Note:    Release returns immediately to the caller. It does not wait 
> for the form to be freed before returning."
> 
> So does Release() wait for everything to be done first before returning 
> to the next line in code?  Do I need to call both Release() and then 
> delete?  Is there something I should do to make sure that Release() has 
> finished prior to calling delete?
> 
> Dan
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2638
Author: Remy Lebeau (TeamB)
Date: Fri, 19 Jan 2007 19:00
48 lines
2861 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message
news:45b0d69a$1@newsgroups.borland.com...

> "Note: When working with form objects, do not explicitly call the
Free
> or Destroy method to free them. Instead, use the Release method,
which
> waits until all event handlers have finished executing."

Do not call Free() or Destroy() ('delete' in C++) while inside one of
the TForm's own event handlers.  That is the only place where you need
to use Release() if the form wants to free itself.  Otherwise, Free()
and Destroy() ('delete') work fine.

> Does this mean I should call "theDialog->Release();" rather than
> "delete theDialog;"?

There is nothing wrong with doing that in the code you showed.  Using
'delete' is the proper thing to do in that situation.

> Reading the "Release()" function call help the note appears
> contradictory to the TForm() section:
>
> "Note: Release returns immediately to the caller. It does not wait
> for the form to be freed before returning."

That is correct.  Release() posts a CM_RELEASE message to the message
queue.  The form is freed when the message is processed later on.
That allows any active and pending event handlers to finish running
before the form is freed.

> So does Release() wait for everything to be done first before
> returning to the next line in code?

No.

> Do I need to call both Release() and then delete?

No.  That will crash your code as the TForm will be freed twice.

> Is there something I should do to make sure that Release() has
> finished prior to calling delete?

Stop using Release() in this situation.  It does not apply at all.


Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2637
Author: Remy Lebeau (TeamB)
Date: Fri, 19 Jan 2007 19:02
24 lines
1856 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message
news:45b0dfca@newsgroups.borland.com...

> Is there anything wrong with doing destruction of a form like this?
> theForm->Release();
> Application->ProcessMessages();

Technically no, but it is not the right way to free the form in this
situation.

> I was noticing without ProcessMessages that theForm was still in
memory..

That is because the message posted by Release() is not processed, so
the form is not freed.

> Is there a better way?

You already know a better way - use 'delete' instead.  There is
nothing in your code that warrants the use of Release().


Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2639
Author: Bruce Salzman
Date: Fri, 19 Jan 2007 19:21
16 lines
1430 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message 
news:45afd751$1@newsgroups.borland.com...
>
> For simplicity, the hardware event is sending a message out of the 
> serial port and waiting for the RXBuffer on taht serial port to 
> reach a certain byte level.
>
> I don't see why I'm running out of resources with the above code.
>

Is it possible that 'theDialogThatCrashes' is consuming resources and 
not cleaning up after itself?

-- 
Bruce 
Re: Creating new TForm causes 'Out of Resources' error on WinXP
#2640
Author: Dan Mayo
Date: Fri, 19 Jan 2007 20:28
36 lines
2845 bytes
Remy Lebeau (TeamB) wrote:

>> Is there a better way?
> 
> You already know a better way - use 'delete' instead.  There is
> nothing in your code that warrants the use of Release().


I do appreciate the help and the comments.
I was under the impression that the Release();  ProcessMessages() call 
actually fixed the problem as my code ran much much longer than it ever 
had before in this loop.

However, it does still occur.

With the straight 'delete' operator, my code lasts approximately 230 
cycles; with the Release(); ProcessMessages() operators instead of 
delete, the code goes nearly 800 cycles.  During each of these cycles 
are several hardware read/write commands, each dynamically creating and 
destroying that form; and with each cycle nearly 24k of memory is saved. 
  The data is stored in a TStringGrid.  Perhaps that is the real 
problem.  I don't quite see why since I can easily open a file and fill 
in a TStringGrid with 2x the amount of data collected during this loop 
and then dynamically create the dialog in question though. But I've been 
wrong before :)

As I said before the form in question is rather simple, and it has a 
TProgressBar, TLabel, and TButton on it; that's it.

I'm confused (1) why this is still happening, although basically Remy 
says I haven't done anything to fix the problem, which I can buy; 
however that brings me to my second confusion (2) why my code 
consistently runs much longer with the Release() than it did with just 
the delete.

Dan
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads