Memory leaks created by the compiler/ run-time system

I have spent nearly two weeks trying to find some memory leaks in a program I am developing. Initially I thought it had something to do with PlaySound (see previous post, 30 Jan 2007) but that was not so. I have now discovered some hidden memory leaks in C++ which I am happy to share with others. (Please note I am using Version 6.0. It’s possible these problems have been fixed in later versions.)

The following code:

CSize test = pDC->GetTextExtent(“ABCDEFG”);

creates a memory leak. I thought that all memory allocated within a function (when not using ‘new’) would be deallocated at the exit, but this is not so. My best guess is this. GetTextExtent has two forms and the form used above needs a CString parameter. The compiler creates a CString to hold the parameter but does not destroy it on exit from the function. The recast statement:

CSize test = pDC->GetTextExtent(“ABCDEFG”, 7);

uses a simple string parameter and does not cause a memory leak.

The same problem occurs with CDC::TextOut, indeed anywhere where there are two forms of the interface, one using a CString and the other a string and length parameter.

The problem also seems to exist with CStrings which change size after their declaration (which is perhaps the single underlying problem). Consider the following:

Void DoSomething()

{

CString message;

if (i==0)

message = “This is the first iteration”;

else

message = “Subsequent iteration”;

..

}

On exit from the function, not all the memory is deallocated! (Change the CString to a char string and it behaves properly.)

There is also a problem with the GDI. In my application I need to draw the same image several times so I was constructing it in a ‘temporary’ device context, bitblt-ing it many times into the destination device context then destroying the temporary device context. I believe I was following the guidelines in the C++ documentation yet every time this led to a memory leak of 16 bytes. Since I draw my picture twice a second this leads to a significant memory leak. My code looked like:

CDC *myDC = new CDC;

myDC->CreateCompatibleDC(pDC);

CBITMAP bm.CreateCompatibleBitmap(pDC, clientRect.right+1, clientRect.bottom+1);

CBITMAP *oldBitMap = myDC->SelectObject(&bm);

// draw the image in myDC

// bitblt many times from myDC into pDC

myDC->SelectObject(oldBitMap);

bm.DeleteObject();

delete myDC;

Because of the memory leak, I made myDC semi permanent in the CView object, constructing it on first draw and deleting it in the CView destructor. But I would like to know if my original code was wrong or if the C++ compiler/run time system is wrong.

These problems were not easy to find because the memory leaks do not seem to appear in the allocated blocks reported by the _Crt functions. They can only be isolated by tracking the .lTotalCount member of the _CrtMemState structure.

I apologise if these problems are already known. Since I have just wasted two weeks finding them, I thought someone else might like to know about them.

Alan



Answer this question

Memory leaks created by the compiler/ run-time system

  • Toolz

    Prasad Somwanshi wrote:
    What Simple Samples means by wrong forum is, there is VC++ language sub category under VC++ category, you should have asked this question there
    No, these VC forums are for VC 2005 only. The dexription of this, the VC General forum, says:

    General questions about Visual C++ 2005, including the development environment, libraries, setup, debugger, samples, and documentation.



  • javert

    You should not post this here unless you have used VC 2005 for it.

    You should create a small sample; one that has just the minimum necessary to recreate the problem. You could generate a MFC project and then just add the minimum necessary to recreate the problem. I think the best way to verify that there is a memory leak is to not put any additional debugging in and just run the progrma using the debugger and see if leaks are reported. I doubt that there are leaks, since if there were, they would have been reported and fixed a long time ago.

    One good reason a small test version could be critical is that it is nearly certain that either you are doing something in your program to cause a leak or you simply are not detecting leaks properly.



  • Ron Rice

    I apologise for posting here. I did not realise this was specifically for users of VC2005. I thought it was a general C++ forum like in the title. Perhaps it should have been called VC2005 C++ General

    Anyway. I know CStrings were causing memory leaks. And I stopped them by converting to character strings. Yes, I could create a small program to demonstrate but this is obviously the wrong forum.

    Alan


  • Jym

    How you are verifying that, there is a memory leak
  • GroovenDrew

    Why not you people try visual leak detector software.Its working for me.

  • lms07424

    What Simple Samples  means by wrong forum is, there is VC++ language sub category under VC++ category, you should have asked this question there,

    Any way, make sure that, there is nothing wrong with memory leak detection technique used by you. There are some standard tools available.
     


  • Sweeps78

    Why you are using this method, have you consider the fact that, there might be temporary variables created on stach, which might have not destroyed, when you have checked for memory.

    Indeed, code in your OP doesn't generate any memory leak.


  • ccote

    I used the _Crt functions. So for example I declare a variable:

    _CrtMemState Vs1;

    then test the total memory allocated at various points in the code to track the allocated memory:

    _CrtMemCheckpoint(&Vs1);
    _RPT1 (_CRT_WARN, "Point 'X' Total now allocated %i\r\n\r\n",Vs1.lTotalCount);

    The messages generated go to a file because I set up a file to receive them:

    HANDLE hcrtfile;
    hcrtfile = CreateFile("Dbg.log",GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN,hcrtfile);
    _CrtSetReportFile(_CRT_ERROR,hcrtfile);
    _CrtSetReportFile(_CRT_ASSERT,hcrtfile);
    _RPT0(_CRT_WARN,"Start of debug file\r\n");

    The output looks like:

    Point 'X' Total now allocated 1446486


  • JoeSmith

    No, these VC forums are for VC 2005 only

    But sub category VC++ language doesn't metnion anything like this,

    its says,

    Issues regarding the C++ language, compiler, and linker. This forum covers all standardized languages, extensions, and interop technologies supported by Visual C++.

    So, I feel OP's question fits there.


  • Memory leaks created by the compiler/ run-time system