?
Solved

memory is leaking

Posted on 2003-02-26
22
Medium Priority
?
1,618 Views
Last Modified: 2013-11-20
Hi, I need your help,
I have memory leaks in my program, and I know what functions are causing them, but not exactly what lines of code are the problem.

I have tried some stuff about decting memory leaks
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

and _CrtDumpMemoryLeaks(); in the function that is leaking.

the debug does agree memory is leaking, but this is where I get stuck it says stuff like this:

Detected memory leaks!
Dumping objects ->
strcore.cpp(118) : {670} normal block at 0x002F63E8, 20 bytes long.
 Data: <            5 yr> 01 00 00 00 07 00 00 00 07 00 00 00 35 20 79 72
strcore.cpp(118) : {665} normal block at 0x002F6338, 20 bytes long.
 Data: <            30yr> 01 00 00 00 07 00 00 00 07 00 00 00 33 30 79 72
strcore.cpp(118) : {660} normal block at 0x002F6288, 21 bytes long.
 Data: <            15yr> 01 00 00 00 08 00 00 00 08 00 00 00 31 35 79 72
strcore.cpp(118) : {652} normal block at 0x002F6180, 14 bytes long.
 Data: <            6 > 01 00 00 00 01 00 00 00 01 00 00 00 36 00
strcore.cpp(118) : {647} normal block at 0x002F60C0, 38 bytes long.
 Data: <            smtp> 01 00 00 00 19 00 00 00 19 00 00 00 73 6D 74 70
oleinit.cpp(86) : {93} client block at 0x002F5258, subtype 0, 68 bytes long.
a CCmdTarget object at $002F5258, 68 bytes long
thrdcore.cpp(166) : {88} client block at 0x002F4F20, subtype 0, 112 bytes long.
a CWinThread object at $002F4F20, 112 bytes long
strcore.cpp(118) : {75} normal block at 0x002F4DE0, 25 bytes long.
 Data: <            C:\a> 01 00 00 00 0C 00 00 00 0C 00 00 00 43 3A 5C 61
strcore.cpp(118) : {74} normal block at 0x002F4D78, 36 bytes long.
 Data: <            C:\a> 01 00 00 00 17 00 00 00 17 00 00 00 43 3A 5C 61
oleinit.cpp(86) : {59} client block at 0x002F4718, subtype 0, 68 bytes long.
a CCmdTarget object at $002F4718, 68 bytes long
strcore.cpp(118) : {54} normal block at 0x002F2B38, 77 bytes long.
 Data: <    @   @   ABCD> 01 00 00 00 40 00 00 00 40 00 00 00 41 42 43 44
{52} client block at 0x002F2A38, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F2A38, 64 bytes long
{50} client block at 0x002F28E8, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F28E8, 64 bytes long
{45} client block at 0x002F2720, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F2720, 64 bytes long
{43} client block at 0x002F25D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F25D0, 64 bytes long
Object dump complete.


okay, and that doesn't really do it for me, cause I don't know what that all means.  It seems like it is saying the memory leak is happening in some MS cpp files, but I know that is not the case, it has to be something in my cpp files, but why are they not referenced?

can anyone please help me?
thanks,
Bob
0
Comment
Question by:bebonham
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 5
  • 4
  • +3
22 Comments
 

Accepted Solution

by:
mastethom earned 400 total points
ID: 8028639
Hi Bob,

The data breaks down like this:

strcore.cpp(118) : {670} normal block at 0x002F63E8, 20 bytes long.
Data: <            5 yr> 01 00 00 00 07 00 00 00 07 00 00 00 35 20 79 72

The file name and the number in parentheses gives you the name of the file and the line number therein where the allocation occurred that is not getting freed.  Here, it's complaining about line 118 in strcore.cpp, which is a source file for the MFC class CString.  The line is:

pData = (CStringData*) new BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)];

and occurs in the AllocBuffer member function.

The phrase "normal block" tells you what kind of memory it's talking about.  Normal is the most common and the MSVC documentation can tell you about the rest of them.  It also tells you the location and size of the block.  The "Data:" section shows you the first 16 bytes of that block in the hopes that it helps you track it down.

Now then, the reason that your source files aren't referenced is because they aren't where the "new" is that isn't getting "delete"d.  That's happening in strcore.cpp.  This is most likely caused by something you're doing with a CString object but since your files aren't the ones explicitly allocating the leaked memory, they aren't referenced in the dump.  See what I mean?

Finally, the number in the curly braces, 670 in the example up there, is the sequence position within your program that that object was allocated.  For instance, the block above was the 670th allocation that occurred during your program's run.  This can help you track it down and kill it.

I use the function _CrtSetBreakAlloc.  All you have to do is call _CrtSetBreakAlloc(x), where x is the number of the allocation you want to trap, somewhere at the beginning of your program and run it in the debugger.  It will break execution at that point and, therefore, at the point where the memory destined to be leaked is allocated.  This will be at line 118 in strcore.cpp but you can then look at the call stack and see where in your own source files that you can causing this to happen and maybe see what you can do about it.

Hope this helps some.  I'm new at this so bear with me, heh.
0
 
LVL 8

Author Comment

by:bebonham
ID: 8028881
thanks that is very good information, I'm going to keep this q open just a little longer, so incase I am still stuck after I try this I can get some more info.

I will get back to you with my results this evening.

Thanks very much for your time,
Bob Bonham

0
 
LVL 23

Expert Comment

by:chensu
ID: 8029634
It is documented in the following article.

Detecting and Isolating Memory Leaks Using Microsoft Visual C++
http://msdn.microsoft.com/library/en-us/dnvc60/html/memleaks.asp?frame=true

See also

HOWTO: Use _crtBreakAlloc to Debug a Memory Allocation
http://support.microsoft.com/default.aspx?scid=kb;en-us;151585

HOWTO: Tracking Down Memory Leaks with _afxBreakAlloc
http://support.microsoft.com/default.aspx?scid=kb;en-us;122307
0
Percona Live Europe 2017 | Sep 25 - 27, 2017

The Percona Live Open Source Database Conference Europe 2017 is the premier event for the diverse and active European open source database community, as well as businesses that develop and use open source database software.

 
LVL 9

Expert Comment

by:BeyondWu
ID: 8029803
Is there another Thread( that use CString) running in your APP?
0
 
LVL 8

Author Comment

by:bebonham
ID: 8029839
All: this code is rough, I was afxOleInit'ing in some execution paths, but some how it still ran?!?

BeyondWu:
there is only one thread, it is trivial, it is only so the dialog is responisve while time consuming functions are running.

Chensu:
I have the Detecting & Isolating Mem Leaks article, I think I was stressed and it seemed confusing, and in the article, it seems like the .cpp that had the error(my.cpp not MS.cpp) was exposed, but I guess I didn't read carefully enough

fortunately, Mastethom told me that it is giving the function that is offending...:) but not the bad code :)

so that helped me.  I will award the points to him once I am comfortable that I can fix this on my own

Thanks a lot guys!
Bob
0
 
LVL 9

Expert Comment

by:BeyondWu
ID: 8029903
Is there any SEH block?
0
 
LVL 9

Expert Comment

by:BeyondWu
ID: 8029967
Actually, the de-constructor of CString will clean all the memory automatically, so there only one situation I can assume to cause the problem, that is the de-constructor hasn't been called properly. When will this case happen. I only can image two situations,
First is, in a thread, you use CString, and at a time, you kill it with TerminateThread APIs, at this situation, the de-constructor of CString will not be called, so throw the memory leak.
Second is, you use a SEH block, in the try{..} block, you use a temp CString variable, if this block cause an exception, it will run the code snippet in catch{..} block, the de-constructor of CString also will not be called, so also cause the memory leak.
I think there are must other situation can caused the same problem, but I only can think of these two case. Anyway, it must caused by that the de-constructor of a CString object hasn't been called.
If I'm wrong, please correct me.:)
0
 
LVL 4

Expert Comment

by:DenL
ID: 8031696
The CString content will not be cleaned in the following simple case as well

CString* pNewStr = new CString(_T"The leaking object");
do not call "delete pNewStr" and you'll get report about a memory leak in the strcore.cpp (the CString's data).
Another case:

class CMyClass
{
  CMyClass():str((_T"The leaking string's data");){}
  CString m_str;
};

CMyClass* pMyClass = new CMyClass;
if you forget to delete the pMyClass - it's destructor and, consequently the CString's one will not be called and you will again be reported about the leaks in the strcore.cpp.

In both cases you should get a report about the leak of the actual object(s) (pointing to the line "CMyClass* pMyClass = new CMyClass;")
0
 
LVL 9

Expert Comment

by:BeyondWu
ID: 8031783
DenL,
LOL, you are right, I forgot the simplest situation.:)
0
 
LVL 22

Expert Comment

by:ambience
ID: 8032650
the mem dump suggest that the application is not exiting normally, its not just CString that is leaking you are leaking an entire list of CDynLinkLibrary objects.

a CCmdTarget object at $002F4718, 68 bytes long
strcore.cpp(118) : {54} normal block at 0x002F2B38, 77 bytes long.
Data: <    @   @   ABCD> 01 00 00 00 40 00 00 00 40 00 00 00 41 42 43 44
{52} client block at 0x002F2A38, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F2A38, 64 bytes long
{50} client block at 0x002F28E8, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F28E8, 64 bytes long
{45} client block at 0x002F2720, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F2720, 64 bytes long
{43} client block at 0x002F25D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F25D0, 64 bytes long

i dont suppose you have tried something fancy with CDynLinkLibrary etc. Are you using any extension dll with your application ? is it dynamically loaded ?

Some part of the code might using AfxLoadLibrary but never calling AfxFreeLibrary ?


0
 
LVL 8

Author Comment

by:bebonham
ID: 8033720
thanks for all the help everyone, I only use the new keyword once, and I am pretty sure that class deletes itself.

So I am still looking, I briefly glanced over the code (searched for new keyword, etc)

but I am thinking it is smtp mime mailer class I got off codeguru that is the problem ...by wes clyburn and pierre codurec?

or something.

well, this afternoon i should have time to really spend some time on this,
Thanks again for all the good suggestions and ideas.

Bob
0
 
LVL 8

Author Comment

by:bebonham
ID: 8035862
I created an dialog with app-wizard, and only added the stuff for the memory leak detection, and it is detecting leaks in the appwizard made dialog.

infact, If I move around where I call
_CrtDumpMemoryLeaks();    
it changes what gets reported, in so much that I could move it to the first executed statement, and no leaks get reported...

why am I getting these memory leak errors from an app wizard created dlg?

btw, the app wiz is also gving these
a CDynLinkLibrary object at $002F2A38, 64 bytes long
{50} client block at 0x002F28E8, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F28E8, 64 bytes long
{45} client block at 0x002F2720, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F2720, 64 bytes long
{43} client block at 0x002F25D0, subtype 0, 64 bytes long.
a CDynLinkLibrary object at $002F25D0, 64 bytes long

please advise me what I am doing wrong.

thanks again, sorry I am having so much trouble.
I am really confused and stuck!

Bob
0
 
LVL 8

Author Comment

by:bebonham
ID: 8035957
A hA!!!

it is because I am using mfc as a shared dll and not as a static linked library.

I will report more soon I hope,

thanks again,
Bob
0
 
LVL 8

Author Comment

by:bebonham
ID: 8036022
I need help using
_CrtSetBreakAlloc();

where do I call it, what should I expect to happen (because nothing seems to now)

Bob
0
 

Expert Comment

by:mastethom
ID: 8036073
If you move around the _CrtDumpMemoryLeaks call, you will certainly get different results as it reports leaks based on the current state of your program AT THAT MOMENT.  So anything that has been allocated that still exists in memory will be reported as a leak even if it will be deleted properly before the program exits.

The best place to dump leaks is therefore at the very end of your program.  I do it in the destructor of my CWinApp derived class.  Try this:

CTestApp::~CTestApp()
{
    CString *str1 = new CString;
    CString *str2 = new CString;

    TRACE("\nPass 1:\n");
    _CrtDumpMemoryLeaks();

    delete str1;
    TRACE("\nPass 2:\n");
    _CrtDumpMemoryLeaks();

    delete str2;
    TRACE("\nPass 3:\n");
    _CrtDumpMemoryLeaks();

    return;
}

Your output will look something like this:

Pass 1:
Detected memory leaks!
Dumping objects ->
C:\Projects\Test\Test.cpp(71) : {65} normal block at 0x009C4C00, 4 bytes long.
 Data: <  R > C8 FF 52 00
C:\Projects\Test\Test.cpp(70) : {64} normal block at 0x009C4BB8, 4 bytes long.
 Data: <  R > C8 FF 52 00
Object dump complete.

Pass 2:
Detected memory leaks!
Dumping objects ->
C:\Projects\Test\Test.cpp(71) : {65} normal block at 0x009C4C00, 4 bytes long.
 Data: <  R > C8 FF 52 00
Object dump complete.

Pass 3:
The thread 0xEE4 has exited with code 0 (0x0).
The program 'C:\PROJECTS\Test\Debug\Test.exe' has exited with code 0 (0x0).

Notice that there are 2 leaks, then 1, then none.  That's because these objects in question still exist when _CrtDumpMemoryLeaks gets called.

Also, note that if you are using MFC as a dynamically loaded DLL then you will always show a memory leak of an CDynLinkLibrary object even if the _CrtDumpMemoryLeaks calls is at the very end of your program like Pass 3 above; Even in a fresh AppWizard created program.  This is because that MFC still has a lot of its own clean up to after your application object disappears.
0
 
LVL 8

Author Comment

by:bebonham
ID: 8036126
thanks again, excellent explaination,

can you help me with how to use _crtSetBreakAlloc()and where to use it?
0
 

Expert Comment

by:mastethom
ID: 8036186
Oh yeah ... one thing you might to try is using a few MFC memory state classes.  You can use those to set checkpoints in your program and only compare memory states between those.  That way you avoid some confusion as to what is your memory and what belongs to the framework.

To trap leaks in your entire application, add a few CMemoryState member variables like these.

CMemoryState memBefore, memAfter, memDiff;

Then call Checkpoint your "before" state as the first line of your CWinApp constructor:

CTestApp::CTestApp(void)
{
    memBefore.Checkpoint();

    // blah blah blah
}

In your destructor, create an "after" check point and the third state variable to compare the difference between the two:

CTestApp::~CTestApp(void)
{
    memAfter.Checkpoint();
    if(memDiff.Difference(memBefore, memAfter))
    {
        // If there's a difference, there's a leak.
    }
    else
    {
        // Otherwise, you're straight.
    }
}

You can use the DumpStatistics and DumpAllObjectsSince members of CMemoryState to generate the same output that _CrtDumpMemoryLeaks gives you.  If you detect leaks with the above example, call them with your "difference" state to see what's leaking.
0
 
LVL 8

Author Comment

by:bebonham
ID: 8036260
I will try that, but isn't it easier to use _crtSetBreakAlloc()?

I just don't know how

Thanks,
Bob
0
 
LVL 8

Author Comment

by:bebonham
ID: 8036279
forget it I got it, thanks a bunch to everyone, I wish I could give you all points!

Bob
0
 

Expert Comment

by:mastethom
ID: 8036332
"can you help me with how to use _crtSetBreakAlloc()and where to use it?"

The best place to call it is in the very beginning of your program.  Think about it: You're using it to trap a certain allocation.  Therefore, if you call it and set the trap AFTER that allocation has occured, it won't do you any good.  So stick it as far up as you can.

The catch with it is that it really doesn't help if, for some reason, the allocation in question doesn't occur at the same time, every time.  _CrtSetBreakAlloc(n) trips on the nth memory allocation your program makes without regard to what that actually is.  For example, say your dump says that the leaked memory is allocated 54th in that run so you call _CrtSetBreakAlloc(54) and run it again.  Your program will now break on the 54th memory allocation *even if the leaked memory is NOT 54th this time.*  Make sense?

So it's important when you get ready to use _CrtSetBreakAlloc that you run the program a few times without it to ensure that you can reproduce the memory leak you want to trap in the same ordinal sequence every time.  This may mean having to select a certain menu item, press a certain button, do both and then some in a specific order, etc.

Also, you can use _CrtSetBreakAlloc with the CMemoryState classes that I talked about earlier since CMemoryState just encapsulates the _Crt* memory functions anyway.
0
 

Expert Comment

by:mastethom
ID: 8036369
"I will try that, but isn't it easier to use _crtSetBreakAlloc()?"

_CrtSetBreakAlloc can be used in concert with what I described above.  The CMemoryState class encapsulates and is an alternative to the _CrtMemCheckpoint, _CrtMemDifference, _CrtDumpMemoryLeaks and a few other functions.
0
 
LVL 8

Author Comment

by:bebonham
ID: 8036705
hi, if anyone could help me with one last question...

all my member variables of my class are comming up as memory leaks,

is this true, or is it because I am calling _CrtDumpMemoryLeaks(); before the dialog is destroyed.

I am currently calling it on the event "OnFinalRelease"

I tried to add a destructor, and it said the body of that function is already defined, but I can't find it anywhere.

can some one help here, is there a destructor already, what gives?

Bob
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses
Course of the Month14 days, 1 hour left to enroll

801 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