Link to home
Start Free TrialLog in
Avatar of chang2008
chang2008Flag for Germany

asked on

Memory leak strcore.cpp(141)

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

Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

>>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;

Do you allocate some object in the the sheet and in the pages?
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
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
Avatar of chang2008

ASKER

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.

See also
"Memory Leak Detection in MFC"
at
http://msdn.microsoft.com/en-us/library/c99kz476(VS.80).aspx
>>>> 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
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.
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

you should use <= instead of <

for(int i=0; i<=myList.GetUpperBound(); i++)
That should be OK.
opps sorry, not OK - use GetCount instead of GetUpperBound
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();
 

ASKER CERTIFIED SOLUTION
Avatar of alb66
alb66
Flag of Italy image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
 
>>>>> 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 <
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
Oh!...wow

It works! ... Thank you very much. :)
Thanks & Have a nice day. :)