Solved

Resource Leak?

Posted on 1998-12-08
2
507 Views
Last Modified: 2013-11-20
Environment VC6.0, Windows 98.

I have a section of code that is throwing a ResourceException, but I can not
quite figure out why. The extract of code is called frequently to draw a
bitmap and a list of annotations. The drawing is repeated approximately once
every 100ms. After running for about 30 seconds the program crashes with an
unhandled resource exception.

Am I doing something bad?

Essentially the steps are:

1) grab an image from the capture card
2) convert the image to a device dependent bitmap.
3) create a memory DC
4) select the DDB into the memory context
5) add a list of annotations to the memory dc
6) bitblt the memory DC to the screen DC.

The resource exception occurs when constructing the CPen or CBrush for one
of the annotations. If I do not create a pen or brush the software does not
crash.

There are only 3 annotations in my list at present. The greater the number
of annotations the quicker the software crashes. This seems to suggest that
the system is running out of resource handles? But I believe I am returning
them to the systems at the end of the function call?

Any help would be much appreciated.
Thanks in advance, here is my code:

            CClientDC dc(this);

            // Get a Device Dependent Bitmap from the DIB.
            HBITMAP handle = GetDDB(bitmap_info, grabbedframe.framebits);

            CDC mem_dc;
            CBitmap* bitmap = CBitmap::FromHandle(handle);

            // select the grabbed frame in to a memory device context.
            mem_dc.CreateCompatibleDC(&dc);
            CBitmap* old_bitmap = mem_dc.SelectObject(bitmap);

            for (int index = 0; index < annotation_list.GetSize(); index++)
            {
                  // select the correct pen and brush for drawing the selected
                  // annotation.
                  CPen pen(annotation_list[index]->pen_style,
                                      annotation_list[index]->pen_width,
                                      annotation_list[index]->pen_colour);
                  mem_dc.SelectObject(&pen);

                  CBrush brush(annotation_list[index]->brush_colour);
                  if (annotation_list[index]->use_null_brush)
                        mem_dc.SelectStockObject(NULL_BRUSH);
                  else
                        mem_dc.SelectObject(&brush);

                  // draw the current annotation.
                  switch(annotation_list[index]->type)
                  {

                        case AZANNOTATION::RECTANGLE:
                              {
                                    mem_dc.Rectangle(CRect(annotation_list[index]->x1,
annotation_list[index]->y1,annotation_list[index]->x2,
annotation_list[index]->y2));
                              }
                              break;

                        case AZANNOTATION::ELLIPSE:
                              {
                                    mem_dc.Ellipse(CRect(annotation_list[index]->x1,
annotation_list[index]->y1,annotation_list[index]->x2,
annotation_list[index]->y2));
                              }
                              break;
                  }
            }



            // draw the bitmap to the screen.

dc.BitBlt(0,0,bitmap_info->bmiHeader.biWidth,bitmap_info->bmiHeader.biHeight
,&mem_dc,0,0,SRCCOPY);

            // remove any objects used in the memory dc.
            // I have also tried storing the last item returned from SelectObject
here. But I believe this does the same thing.
            mem_dc.SelectObject(old_bitmap);
            mem_dc.SelectStockObject(NULL_BRUSH);
            mem_dc.SelectStockObject(BLACK_PEN);

            // free up the bitmap handle.
            DeleteObject(handle);
0
Comment
Question by:sdj
  • 2
2 Comments
 
LVL 3

Accepted Solution

by:
plaroche earned 200 total points
ID: 1325914
You create your pen and brush in the for loop, and select a null brush and pen outside of that loop. Not very elegant.

Save the return value from selectobject and re-select it at the end of the loop. Thus your WIN32 graphical objects handles will be freed correctly.
0
 
LVL 3

Expert Comment

by:plaroche
ID: 1325915
Here's an example:

CPen* pOldPen;
CDC dc;

for(int i=0; i<1000;i++) {
  CPen  pen(PS_SOLID, 1, RGB(0,0,0) );
  pOldPen = (CPen*)dc.SelectObject(&pen);
  // Draw something
  dc.MoveTo(0,0);
  dc.LineTo(100,100);
  dc.SelectObject(pOldPen);
}

For eevry selectobject of a pen you must re-select the old one before that pen gets destroyed. Since your pen is created on the stack you must do it before the end of the loop.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
GIF file bit manipulation for color change 5 107
Looking for a specific application/software 2 104
ffmpeg - "rtsp://...... Operation not permitted" 4 73
zeroFront challenge 7 79
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is a video that shows how the OnPage alerts system integrates into ConnectWise, how a trigger is set, how a page is sent via the trigger, and how the SENT, DELIVERED, READ & REPLIED receipts get entered into the internal tab of the ConnectWise …

929 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

9 Experts available now in Live!

Get 1:1 Help Now