Click to See Complete Forum and Search --> : Memory leaks... in MFC ???


Luc B.
June 2nd, 1999, 01:57 PM
Can anyone please explain how I can avoid these kind of messages in the debug window of VC 5.0 ???

Thanx in advance for any help :)

Here is a sample of my program executed in debug mode :

Detected memory leaks!
Dumping objects ->
{138} client block at 0x008C2A40, subtype 0, 16 bytes long.
{126} client block at 0x008C26E0, subtype 0, 16 bytes long.
{121} client block at 0x008C2580, subtype 0, 16 bytes long.
{117} client block at 0x008C2460, subtype 0, 16 bytes long.
{115} client block at 0x008C23E0, subtype 0, 16 bytes long.
{111} client block at 0x008C22E0, subtype 0, 16 bytes long.
{103} client block at 0x008C1A80, subtype 0, 16 bytes long.
{94} client block at 0x008C13F0, subtype 0, 16 bytes long.
{81} client block at 0x008C1CD0, subtype 0, 16 bytes long.
strcore.cpp(76) : {79} normal block at 0x008C1C50, 23 bytes long.
Data: < veri> 01 00 00 00 0A 00 00 00 0A 00 00 00 76 65 72 69
strcore.cpp(76) : {78} normal block at 0x008C1C10, 21 bytes long.
Data: < veri> 01 00 00 00 08 00 00 00 08 00 00 00 76 65 72 69
strcore.cpp(76) : {68} normal block at 0x008C1960, 86 bytes long.
Data: < I I \\FC> 01 00 00 00 49 00 00 00 49 00 00 00 5C 5C 46 43
strcore.cpp(76) : {65} normal block at 0x008C1860, 78 bytes long.
Data: < A A \\FC> 01 00 00 00 41 00 00 00 41 00 00 00 5C 5C 46 43
strcore.cpp(76) : {64} normal block at 0x008C1810, 38 bytes long.
Data: < C:\A> 01 00 00 00 19 00 00 00 19 00 00 00 43 3A 5C 41
{60} client block at 0x008C16F0, subtype 0, 60 bytes long.
{59} client block at 0x008C1690, subtype 0, 60 bytes long.
{58} client block at 0x008C1630, subtype 0, 60 bytes long.
{53} client block at 0x008C14A0, subtype 0, 16 bytes long.
{49} client block at 0x008C12F0, subtype 0, 8 bytes long.
strcore.cpp(76) : {45} normal block at 0x008C1120, 43 bytes long.
Data: < Test> 01 00 00 00 1E 00 00 00 1E 00 00 00 54 65 73 74
{44} client block at 0x008C0E30, subtype 0, 268 bytes long.
Object dump complete.

Grace
June 2nd, 1999, 10:12 PM
CArray has memory leak.
if u really dont like it, use STL vector

Yogen M
June 2nd, 1999, 10:25 PM
This shows leaks in your program that uses MFC classes and not in MFC itself.
I'm pretty sure from the warnings that they are coming from CString class.
See if you have any CString objects for which u've forgotten to call ReleaseBuffer after a
call to GetBuffer.

Paul McKenzie
June 3rd, 1999, 01:23 AM
You probably called "new" without a "delete" call. It looks like a CString or CStringArray was involved in the instantiation of an object that was not deleted. The reason I know this is that the "strcore" Data has something that looks like a user defined string (like "Test"). It should look like data that you are familiar with.

MFC does have memory leaks, but the leaks have been mostly GDI related, not CStrings.

Regards,

Paul McKenzie

Luc B.
June 3rd, 1999, 08:12 AM
You mentionned that memory leaks in MFC are mostly located with GDI objects... In my code I use "new" to create a CDC object here is the sample code :


iResults = GetUpdateRect(&r);
if (iResults != 0) {
BeginPaint(&ps);

curHDC = new CDC();
curHDC = GetDC();
curHDC->SetTextColor(RGB(0,0,255));
curHDC->SetBkMode(TRANSPARENT);

//Some drawing stuff...

curHDC->DeleteDC();
curHDC = NULL;
}




Can the leaks be caused by this... I tried to "delete" curHDC but I get an Assertion error !?!?!?

chiuyan
June 3rd, 1999, 09:18 AM
if you new something, then YOU have to delete it. The reason your delete of curHDC is faling (I am guessing here) is because you new a CDC, and then immediately overwrite that with whatever GetDC returns, so you are then trying to delete the DC that was returned by windows & you did not new that one. I suspect that the
curHDC = new CDC ();


line in your code is unnecessary.

I do not think that this is the cause of all of your memory leaks though, you need to just search for new, and make sure that everything you new you also delete somewhere (and be sure to use delete[] where appropriate)

--michael

June 3rd, 1999, 09:19 AM
Im new to the programming of C++ but as far as I know this is what you do wrong
if you call it that way you create a new DC
then throw away the new DC since you replace the pointer to the new DC with the pointer you get from GetDC()
After that you delete the structure at the adress you got from the GetDC()

Now you have 2 problems
1) lost memory
2) you killed a structure needed by the program

try this for a change

iResults = GetUpdateRect(&r);
if (iResults != 0) {
BeginPaint(&ps);
curHDC = GetDC();
curHDC->SetTextColor(RGB(0,0,255));
curHDC->SetBkMode(TRANSPARENT);
//Some drawing stuff...
curHDC = NULL;
}

Paul McKenzie
June 3rd, 1999, 09:43 AM
There are several things wrong with what you are doing. I'm not sure what you are trying to accomplish, but here are a few things that I've noticed:

First, if you're calling BeginPaint(), you must be in a WM_PAINT or an OnPaint() handler. Also, the DC has already been set up for you when BeginPaint() is called. There is no need to create another. The DC is in the PAINTSTRUCT member hdc. This is assuming that you are attempting to paint to the DC specified by the PAINTSTRUCT. If this is the case, you must also call EndPaint() to release the DC, which you do not do. Also, since the hdc in the PAINTSTRUCT is an HDC and not an MFC CDC object, you will have to call CDC::Attach() if you want to connect the HDC DC to a CDC object:

BeginPaint(&ps);
CDC curHDC;
curHDC.Attach(ps.hdc);
...
curHDC.Detach(); // when we are done
EndPaint(&ps);

Second, CDC aren't created with "new" as you have done. Here is how it should be done without using "new":

Assuming we are in a CWnd object:
CDC *pDC = GetDC();
...
pDC->whatever();
...
ReleaseDC(pDC);
...

This is assuming that you wanted to do this, given that the BeginPaint() was called with a DC already available in the PAINTSTRUCT ps.


If you wanted to use "new", the following can be tried:

CDC *pDC = new CDC;
pDC->Attach(/* an hdc */);
...// Do stuff with CDC
pDC->Detach();
delete pDC;

Regards,

Paul McKenzie

Luc B.
June 3rd, 1999, 09:49 AM
>It looks like a CString or CStringArray was involved in the instantiation of an object that was not deleted.

Yep I do have a couple of CStrings in my main window class and one CStringArray... But they were not created by "new"... So how can I delete them ??? Is CString::Empty() enough !?!?!

Thanx for your help :)

Gomez Addams
June 3rd, 1999, 12:59 PM
As you probably know, memory leaks are allocations that are made
and are not released. There are several leak messages there that
have no location noted. It will probably help to know where they came
from so you can track them down easier. Here are a few things that
might help :

Make sure that you have this in all of your modules :


#ifdef _DEBUG
#define new DEBUG_NEW
#endif




Another thing I do is to add this little snippet in OnInitInstance :
(actually, I made this a function that is called from OnInitInstance)


#ifdef _DEBUG

int tmp = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
tmp |= _CRTDBG_LEAK_CHECK_DF;
tmp &= ~(_CRTDBG_CHECK_CRT_DF );
_CrtSetDbgFlag( tmp );

#endif




Lastly, if you use any of the malloc family, add this in stdafx.h or some other
header that all modules include.


#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>




The last piece of advice I have is to use stack-based objects as much as
possible because they are automatically destroyed when the object goes
out of scope. What this means is that when you make an instance of an
object as a function is entered it will be destroyed for you when the function
returns. This way you don't have to remember to delete objects created
with new. This applies to nearly objects (I think) including GDI wrappers
like CBrush and CPen.

Best of Luck.

chiuyan
June 3rd, 1999, 01:12 PM
if you did not new them, then you do not have to delete them. However, if they are members of some class that you new, but then never delete--they will never be destroyed either (The member variables of a class are not destroyed until the class is destroyed). This is probably where the memory leaks are coming from.

--michael