Memory leak strcore.cpp(141)

chang2008
chang2008 used Ask the Experts™
on
Hallo everyone,

I have a question about memory leak. I use Visual Studio .Net MFC.

I have 1 propertysheet and 2 classes for 2 pages in the sheet. Memory leak occurs after ExitInstance() which I can't debug and it does not appear immediately. I have to wait almost 1 minute, the leak will be shown as follow:

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {453} normal block at 0x070DF020, 34 bytes long.
 Data: <<N              > 3C 4E BC 07 11 00 00 00 11 00 00 00 01 00 00 00
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {452} normal block at 0x070DEFD0, 20 bytes long.
 Data: <<N              > 3C 4E BC 07 03 00 00 00 03 00 00 00 01 00 00 00
{451} client block at 0x070DEF58, subtype c0, 56 bytes long.
faulted while dumping object at $070DEF58, 56 bytes long
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {432} normal block at 0x070DDA50, 34 bytes long.
 Data: <<N              > 3C 4E BC 07 11 00 00 00 11 00 00 00 01 00 00 00
{431} client block at 0x070DD9B8, subtype c0, 88 bytes long.
faulted while dumping object at $070DD9B8, 88 bytes long
Object dump complete.

One more thing,
when I comment out the page1

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {433} normal block at 0x028CDA30, 34 bytes long.
 Data: <<N              > 3C 4E B2 07 11 00 00 00 11 00 00 00 01 00 00 00
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {432} normal block at 0x028CD9E0, 20 bytes long.
 Data: <<N              > 3C 4E B2 07 03 00 00 00 03 00 00 00 01 00 00 00
{431} client block at 0x028CD968, subtype c0, 56 bytes long.
faulted while dumping object at $028CD968, 56 bytes long
Object dump complete.

when I comment out the page2

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {428} normal block at 0x06BBDA50, 34 bytes long.
 Data: <<N|             > 3C 4E 7C 07 11 00 00 00 11 00 00 00 01 00 00 00
{427} client block at 0x06BBD9B8, subtype c0, 88 bytes long.
faulted while dumping object at $06BBD9B8, 88 bytes long
Object dump complete.

How can I solve the problem? Thank you very much in advance. :)

========== Initialize ==========
 
mainSheet = new TreeSheet::CTreeSheet;
 
page1 = new CPage1();
page2 = new CPage2();
 
mainSheet->AddPage(page1);
mainSheet->AddPage(page2);
 
=============================
 
========== destructor ==========
 
delete mainSheet; 
delete page1; 
delete page2; 
 
=============================

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
AndyAinscowFreelance programmer / Consultant

Commented:
>>I use Visual Studio .Net MFC.
Actually MFC is nothing to do with .NET


In the page do you code like
CString* s = new CString();

If you do then you are missing the
delete s;

Commented:
Do you allocate some object in the the sheet and in the pages?
AndyAinscowFreelance programmer / Consultant

Commented:
Also note code like the following is also going to give a memory leak
struct st
{
CString s;
}


in the property page
struct* st = new struct;

//delete st;   //missing delete to free the memory of the CString as well as the struct
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

Commented:
Put the following at the beginning of each .cpp file:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

It should help you to find where the object are allocated.

http://msdn.microsoft.com/en-us/library/tz7sxz99(VS.80).aspx

Author

Commented:
Oops! ... sorry. It is Visual Studio 2008.

I don't use any CString* s = new CString();
I use also CObArray but I'm surely that I have delete it in destructor.

Commented:
See also
"Memory Leak Detection in MFC"
at
http://msdn.microsoft.com/en-us/library/c99kz476(VS.80).aspx

Commented:
>>>> I use also CObArray but I'm surely that I have delete it in destructor.

You need also to delete every object allocated dinamically with new and added to the CObArray
AndyAinscowFreelance programmer / Consultant

Commented:
Anything you create with a new operator needs a corresponding delete operation to free the memory else you have a memory leak.  The destructor of a collection (eg. array) does NOT do that for you.

Author

Commented:
What I have done below is not enough to delete CObArray?

It would be nice, if any one show me the example code about object allocated dynamically and delete the object.

Thank you very much in advance. :)
========== Initialize Page 1==========
 
this->currentPosition = 0;
c1 = new component("AAA", 1, 2, 3);
this->myList.Add(c1);
c2 = new component("BBB", 4, 5, 6);
this->myList.Add(c2);
 
=============================
 
========== destructor ==========
 
//*** Delete CObArray.
for(int i=0; i<myList.GetUpperBound(); i++) 
{
     delete myList.GetAt(i);
}
myList.RemoveAll();
 
=============================

Open in new window

Commented:
you should use <= instead of <

for(int i=0; i<=myList.GetUpperBound(); i++)
AndyAinscowFreelance programmer / Consultant

Commented:
That should be OK.
AndyAinscowFreelance programmer / Consultant

Commented:
opps sorry, not OK - use GetCount instead of GetUpperBound

Commented:
You can try this code for the array clear:
component* p = NULL;
for(int i=0; i<myList.GetUpperBound(); i++)
{
     p = myList.GetAt(i);
     delete p;
     p = NULL;
}
myList.RemoveAll();
 

Commented:
The problem in your code is that you delete only one object (c1) instead of two.

You have to equivalent possibility:

// GetUpperBound() returns the largest array index:
for(int i=0; i<=myList.GetUpperBound(); i++)                         <---------  use "<="
{
     delete myList.GetAt(i);
}
myList.RemoveAll();

or

// GetSize() ( or GetCount() ) returns the number of element
for(int i=0; i<myList.GetSize(); i++)                         <---------  use "<"
{
     delete myList.GetAt(i);
}
myList.RemoveAll();

Commented:
Nice. :)
So just a very small addition:
int nCount = myList.GetSize();
component* p = NULL;
while (nCount > 0)
{
  nCount--;
  p = myList.GetAt(nCount);
  if (p != NULL)
  {
    delete p;
    p = NULL;
  }
}
myList.RemoveAll();

longer. but this approach, from my POV, does not give a chance for a leak.
 

Commented:
>>>>> if (p != NULL)
delete NULL pointer is allowed in C++ so you don't need this check.

>>>>> p = myList.GetAt(nCount);
you cannot assign a CObject* to a component* (you need a cast)

>>>>>  p = NULL;
assign NULL to p is useless since it is no more used in the code.


So, chang2008's code is quite OK, but she must use <= instead of <
AndyAinscowFreelance programmer / Consultant
Commented:
This (from myself) does not give memory leak
for(int i=0; i<myList.GetCount(); i++)                        
{
     delete myList.GetAt(i);
}
myList.RemoveAll();

This (from alb66) does not give memory leak
for(int i=0; i<=myList.GetUpperBound(); i++)                        
{
     delete myList.GetAt(i);
}
myList.RemoveAll();


Both are a lot shorter and simpler than using the while loop.

Commented:
Agreed. :)
If I see right it is three strings which were not freed.

Does the object which you delete at

   delete myList.GetAt(i);

has 3 string members?

If not there are still more leaks.

Check all occurrences of CObArray::GetUpperBound() and replace them by CObArray::GetCount or CObArray::GetSize as suggested by AndyAinscow. If your loops always start by 0 and have a less < for termination you'll make your life happier ...

Another possibility where leaks may occur are static CString member variables or CString member variables of static class instances. The leak output occurs before destructors of static class members have run.

Author

Commented:
Oh!...wow

It works! ... Thank you very much. :)

Author

Commented:
Thanks & Have a nice day. :)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial