Thread: freeing memory..

  1. #1
    Registered User
    Join Date
    Feb 2002
    Posts
    93

    Question freeing memory..

    i am a little confused on something .. wondering if someone could clear this up for me...

    HBRUSH hbrush;
    HBRUSH old_brush;
    hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(22,22,22));
    old_brush = (HBRUSH)SelectObject(hdc,hbrush);
    SelectObject(hdc,old_brush);
    Ellipse(hdc,30,30,130,130);
    DeleteObject(hbrush);


    this is how i have seen it coded in tutorials and this is supposedly the proper way to free memory, etc.... but i'm not getting it..
    could someone explain to me why this is the correct way?
    From looking at it appears that old_brush is never freed...

    this is how i thought it should be coded...

    HBRUSH hbrush;
    hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(22,22,22));
    SelectObject(hdc,hbrush);
    Ellipse(hdc,30,30,130,130);
    DeleteObject(hbrush);

  2. #2
    Registered User
    Join Date
    May 2002
    Posts
    317
    OldBrush is never freed because it is the default windows brush, or the brush that was selected when your program came to this bit of code. The reason you don't delete old_brush is because you never created it:

    [code]
    HBRUSH hbrush; /* create a handle for
    HBRUSH old_brush; brushes */
    hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(22,22,22)); /*create a brush*/
    old_brush = (HBRUSH)SelectObject(hdc,hbrush); /*assign hbrush to current device context. SelectObject returns the handle to the previously selected brush(in this case)*/
    SelectObject(hdc,old_brush); /*Assign original brush to device context*/
    Ellipse(hdc,30,30,130,130);
    DeleteObject(hbrush); //delete brush you created.

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Umm... why the heck do you SelectObject(hbrush), then right away SelectObject(old_brush) THEN do the drawing??

    You should select hbrush, and store the original brush in old_brush (you did that already, with old_brush = SelectObject(hdc, hbrush)), then draw the ellipse. After you're done drawing the ellipse, you select old_brush back into hdc, so that the HDC is exactly as you found it. Then you delete hbrush. You need to use old_brush, otherwise you cannot put the original brush back into the HDC - it will have disappeared.

    *BTW, correct me if I'm wrong: HBRUSH's (and all other things starting in H) work sort of like pointers:

    Code:
    HBRUSH hBrush;
    HBRUSH hBrush2;
    
    //This is what i THINK:
    hBrush = CreateSolidBrush(...);
    hBrush2 = hBrush;
    DeleteObject(hBrush2); //now both hBrush and hBrush2 are deleted
    So (again, I think), if you tried to delete old_brush, you would delete the brush in hdc, thus defeating the purpose of having old_brush in the first place. So in the end, if you deleted old_brush, the program would run exactly the same as the code that you thought up yourself.

    **Did that help?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Unregistered
    Guest
    A HBRUSH is a HANDLE or kind of pointer to a object. Once you use the 'create' function you have allocated it an object and so memory. You must return this memory by freeing it as you would any other memory.

    The same applies to the HDC. It is also a handle, when you 'get' or 'create' it you give it an object. To successfully free it you must return it to the original state by selecting in the original objects.


    I don't think the code is correct, you create a brush but never use it.
    Code:
    //create and select brush
    hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(22,22,22)); 
    old_brush = (HBRUSH)SelectObject(hdc,hbrush);
    //use brush
    Ellipse(hdc,30,30,130,130); 
    //clean up
    SelectObject(hdc,old_brush); 
    DeleteObject(hbrush);
    At the end of this code snippet the brush has been freed and the HDC is back to the original state ready to be ReleaseDC() or DeleteDC() 'ed.

  5. #5
    Registered User
    Join Date
    May 2002
    Posts
    317
    I'm sure the code posted above was just an example and had no real purpose. Yes you can treat HANDLES as pointers, kindof.
    Handles are,traditionally, memory locations to hardware features, like your mouse and video display.However with API things get a little tricky because the boundry between abstract 'objects' and physical properties blur. Do Not Delete old_brush. You will remove the brush selected into windows to do your drawing, now you have no brush selected and windows will not know how to draw anything further, this is a bad thing.

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Do Not Delete old_brush. You will remove the brush selected into windows to do your drawing, now you have no brush selected and windows will not know how to draw anything further, this is a bad thing.
    *Thanks for the paraphrase and the clarification about why it is bad not to have a brush anymore

    P.S. Do NOT delete old_brush.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Feb 2002
    Posts
    93
    hmmm i thought i understood what u guys were talking about but when i went to test out different codes i got the same result... once again i am lost..
    -----------------------------------
    HBRUSH hbrush;
    HDC hdc;
    PAINTSTRUCT ps;

    switch (iMsg)
    {
    case WM_PAINT:
    hdc = BeginPaint(hwnd,&ps);
    hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(50,50,50));
    SelectObject(hdc,hbrush);
    Ellipse(hdc,25,25,100,100);
    DeleteObject(hbrush);
    Ellipse(hdc,100,100,200,200);//put this below delectobject to ---------------------------------------------see what would happen..
    EndPaint(hwnd,&ps);
    break;

    case WM_LBUTTONDOWN:
    hdc = GetDC(hwnd);
    Ellipse(hdc,150,150,300,300);
    ReleaseDC(hwnd,hdc);
    break;
    -------------------------------------------------
    HBRUSH hbrush;
    HBRUSH hbrush2;
    HDC hdc;
    PAINTSTRUCT ps;

    switch (iMsg)
    {
    case WM_PAINT:
    hdc = BeginPaint(hwnd,&ps);
    hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(50,50,50))
    hbrush2 = SelectObject(hdc,hbrush);
    Ellipse(hdc,25,25,100,100);
    DeleteObject(hbrush);
    Ellipse(hdc,100,100,200,200);
    EndPaint(hwnd,&ps);
    break;

    case WM_LBUTTONDOWN:
    hdc = GetDC(hwnd);
    Ellipse(hdc,150,150,300,300);
    ReleaseDC(hwnd,hdc);
    break;
    -------------------------------
    both sets of code produce the same result.. when window created two circles are created filled in with hatch lines.. when left mouse button clicked a third circle with no hatch filling is created..in the first set of code i deleted the hbrush without creating a second brush yet it knew how to create a circle with a "default brush".. with the way u guys were talking shouldn't the first set of code not be able to draw the third circle?

    sorry for the length of this post but i really want to figure this out.. can't believe i've been stuck on this long.. argggg..

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    ?... did the first set of code draw both ellipses (when the app starts) with hatch?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    Registered User
    Join Date
    Feb 2002
    Posts
    93
    yeah the first two ellipses were both hatched in.. the third one is created when the left mouse button is clicked and it had a thin black line with a complete white inside...

    this was the result when I ran both sets of code...

  10. #10
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    waiiit a minute... the only difference between the two sets of code is that you put the original HBRUSH from hdc into hbrush2. But effectively, there is no difference between the two sets. This is what you did for the first:

    Code:
    switch (iMsg) 
    { 
       case WM_PAINT: 
          hdc = BeginPaint(hwnd,&ps);
          hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(50,50,50));   Create hbrush
          SelectObject(hdc,hbrush);   //select hbrush
          Ellipse(hdc,25,25,100,100);   //draw ellipse
          DeleteObject(hbrush);   //delete hbrush
          Ellipse(hdc,100,100,200,200);   //draw ellipse (?...) 
          EndPaint(hwnd,&ps);
          break;
    
       case WM_LBUTTONDOWN:
          hdc = GetDC(hwnd);
          Ellipse(hdc,150,150,300,300);   //draw ellipse
          ReleaseDC(hwnd,hdc); 
          break;
    }
    This is what you did in the second:

    Code:
    switch (iMsg) 
    { 
       case WM_PAINT: 
          hdc = BeginPaint(hwnd,&ps);
          hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(50,50,50));   Create hbrush
          hbrush2 = SelectObject(hdc,hbrush);   //select hbrush, put the original brush in hbrush2
          Ellipse(hdc,25,25,100,100);   //draw ellipse
          DeleteObject(hbrush);   //delete hbrush
          Ellipse(hdc,100,100,200,200);   //draw ellipse (?...) 
          EndPaint(hwnd,&ps);
          break;
    
       case WM_LBUTTONDOWN:
          hdc = GetDC(hwnd);
          Ellipse(hdc,150,150,300,300);   //draw ellipse
          ReleaseDC(hwnd,hdc); 
          break;
    
          //you still haven't selected hbrush2 back into hdc,
          //and it will now go out of scope!
    }
    * and by the way, you did put the closing curly brace in your own code, right?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  11. #11
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    from DeleteObject() help

    >>If the specified handle is not valid or is currently selected into a DC, the return value is zero.

    >>Do not delete a drawing object (pen or brush) while it is still selected into a DC.

    >>When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be deleted independently.


    Don't we read the help?

    And so will not delete the brush. This is why you have to 'push' the new brush out by SelectObject() the old back.

    Try a loop in which you create a brush but do not free it. See how long it takes to stop drawing anything or crash.
    Last edited by novacain; 06-11-2002 at 10:32 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  12. #12
    Registered User
    Join Date
    Feb 2002
    Posts
    93
    or is currently selected into a DC oh i didn't realize this was the case... makes sense now... thought i was deleting the object properly but i really wasn't.

    One last tiny question.. is this the only way to do it or will the following code work...

    Code:
    case WM_LBUTTONDOWN:
          hdc = GetDC(hwnd);
          hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(50,50,50));   
          SelectObject(hdc,hbrush);   
          Ellipse(hdc,150,150,300,300);   
          ReleaseDC(hwnd,hdc); 
          DeleteObject(hbrush);      
    break;

    since the hdc is released before i delete the brush then wouldn't that mean that the brush is no longer selected into a dc?

    once again thanx for all the help... i've been going through the MSDN library alot but is tough to understand if u are doing if right if the compiler returns no error
    Last edited by tegwin; 06-11-2002 at 10:46 PM.

  13. #13
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    No. It is a memory leak.

    Two brushes are lost each msg, one for the brush and one from the original brush in the DC, may be even the DC's mem will be lost.

    You must return the DC to its original state before you can release it.

    Code:
    case WM_LBUTTONDOWN:
          hdc = GetDC(hwnd);
          hbrush = CreateHatchBrush(HS_FDIAGONAL,RGB(50,50,50));   
          hOrigBrush=SelectObject(hdc,hbrush);  
          Ellipse(hdc,150,150,300,300);   
          SelectObject(hdc,hOrigBrush);  
          ReleaseDC(hwnd,hdc); 
          DeleteObject(hbrush);      
    break;
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  14. #14
    Registered User
    Join Date
    Feb 2002
    Posts
    93
    well i must say u all were very helpful..... and i'm actually out of questions... amazin' aint' it? well thanx for the quick replies and help........


    I FINNALLY GET IT!!!!! HOORAY


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. memory freeing function
    By johndoe in forum C Programming
    Replies: 4
    Last Post: 02-17-2006, 02:08 AM
  2. Freeing memory for non-pointer variables
    By SuperGodAntMan in forum C++ Programming
    Replies: 7
    Last Post: 02-11-2006, 01:30 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. memory allocation and freeing
    By Jase in forum Linux Programming
    Replies: 1
    Last Post: 05-25-2003, 06:26 AM
  5. freeing memory
    By mart_man00 in forum C Programming
    Replies: 1
    Last Post: 04-27-2003, 08:51 PM