Solved

Memory Leak using CObArray

Posted on 1997-10-13
14
714 Views
Last Modified: 2013-11-20
I'm trying to implement a CObArray of a class I derived from CObject.


class CMyClass : public CObject
{
private:
      CString m_name;
      CString m_grade;
      CString m_credits;

public:
      // Constructors
      CMyClass();
      CMyClass(CString, CString, CString);
      CMyClass(const CStorGrades&);
      
      // Destructor
      ~CMyClass();

      // Accessors
      void SetName(CString);
      CString& GetName();
      
      void SetGrade(CString);
      CString& GetGrade();

      void SetCredits(CString);
      CString& GetCredits();
};

I declare the CObArray :

      CObArray m_MyClasses;

And try to initialize it:

      CMyProgDoc *pDoc=GetDocument();

      pDoc->m_MyClasses.SetSize(5);

      for (int i=0; i<5; i++)
      {
            pDoc->MyClasses.SetAt(i, new MyClass);
      }

At runtime, a memory leak is asserted at this point.

I'm using MSVC 4.0. Does this look wrong to anyone?

-- please respond via email
   Thanks,
      Corey
0
Comment
Question by:sanderc2
  • 6
  • 5
  • 2
  • +1
14 Comments
 
LVL 7

Expert Comment

by:faster
ID: 1308073
Please paste your complete source for defining the class.
0
 

Author Comment

by:sanderc2
ID: 1308074
Edited text of question
0
 

Author Comment

by:sanderc2
ID: 1308075
Edited text of question
0
 
LVL 3

Accepted Solution

by:
jaba earned 100 total points
ID: 1308076
As i think, you doing this in CView derived class:
class CMyView: public CView {
[...]
CObArray m_MyClasses;
};

When you have to write:
CMyView::~CMyView ()
{
for ( int i = 0 ; i < m_MyClasses.GetCount() ; i ++ ) {
   delete m_MyClasses.[i];
}
m_MyClasses.RemoveAll();
}

Because CObList and CObArray containing only pointers on objects and dont delete objects in destructor. You have to delete objects yourself.
0
 

Author Comment

by:sanderc2
ID: 1308077
The assumption that I am working from the CView class is correct.

My current destructor is:

CGradesView::~CGradesView()
{
      CGradesDoc *pDoc=GetDocument();

      int size = pDoc->m_courses.GetSize();
      for(int i=0; i<size; i++)
      {
            CStorGrades *Sg;
            Sg = (CStorGrades*)pDoc->m_courses.GetAt(i);
            pDoc->m_courses.RemoveAt(i);
            delete Sg;
      }
}

now that I look at it, that's definitely wrong
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1308078
MFC doesn't do memory leak asserts, does it?

Do you mean you found a memory leak and it said this was where the memory was allocated?

If so, then it is because you have't deleted the objects pointed to by the pointers in the array BEFORE you remove them from the array.

0
 

Author Comment

by:sanderc2
ID: 1308079
This is MVC 4.0
I recieve a message from a debug assert that reads:

Debug Assertion Failed!
line 44
file: objcore.cpp  (MFC source file)

the failed assertion is in the CObject::IsKindOf(...) function.

it fails on the line:  ASSERT(this != NULL);

The documentation for the new operator says that CObject overloads it to do memory leak assertion/detection:

    "In the Debug version, operator new participates in an      allocation-monitoring scheme designed to detect memory      leaks."

the build status reads:
   Loaded symbols for 'C:\WINDOWS\SYSTEM\MFC40D.DLL'
   Loaded symbols for 'C:\WINDOWS\SYSTEM\MSVCR40D.DLL'
   The program 'D:\...\Grades.exe' has exited with code 0 (0x0).

but used to read:
   Loaded symbols...etc
   Loaded symbols...etc  
   Memory leak detected...etc.

The program still doesn't work->same assertion failed.

-- Corey

0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 10

Expert Comment

by:RONSLOW
ID: 1308080
int size = pDoc->m_courses.GetSize();
for(int i=0; i<size; i++)
{
CStorGrades *Sg;
Sg = (CStorGrades*)pDoc->m_courses.GetAt(i);
pDoc->m_courses.RemoveAt(i);
delete Sg;
}
}

Yes - that is wrong, as it will try to remove items past the end of the array, and will not remove others (in fact it will only remove every second one.

Change the GetAt(i) and RemoveAt(i) to GetAt(0) and RemoveAt(0).

Are you sure that the memory leak is at the point you indicated in the code.  if so, then ,aybe the problem is in your constructor?

If you would like me to continue helping here, please post this as another question - it costs me ten points every time because the question has already had an answer accepted - which it appears has not fixed the problem.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1308081
Actually, I think I've just found your problem (and the answer)...

Please post the question again so I can (attempt to) answer it for you.

Roger


0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1308082
Actually, I think I've just found your problem (and the answer)...

Please post the question again so I can (attempt to) answer it for you.

Roger


0
 

Author Comment

by:sanderc2
ID: 1308083
I have a class

class CMyClass : public CObject
{
  private:
    CString m_name;
    CString m_credits;
    CString m_grade;

  public:
   //constructors/destructor
   //accessor functions
};

I declare a CObArray in the CMyProjDoc class:
    CObArray m_courses;

And initialize it in the CMyProjView class:

CMyProjView::CMyProjView()
{
        CGradesDoc *pDoc=GetDocument();

      pDoc->m_courses.SetSize(5);
      for(int i=0; i<5; i++)
      {
            pDoc->m_courses.SetAt(i, new(CStorGrades));
      }
}

and destruct it: (as per advice from jaba)

CMyProjView::~CMyProjView()
{
      CGradesDoc *pDoc=GetDocument();

      for ( int i=0; i<pDoc->m_courses.GetSize(); i++)
      {
            delete pDoc->m_courses[i];
    }
    pDoc->m_courses.RemoveAll();
}

The problem arises in a debug assertion at:
 
  line 44
  file: objcore.cpp (MFC source file)
  in routine: CObject::IsKindOf(...)
  on the statement: ASSERT(this != NULL)

The documentation on CObject says that the overloaded new operator:

  "In the Debug version, operator new participates in an allocation-monitoring scheme designed to detect memory leaks."

And the debugger reported that:

   Loaded symbols for 'C:\WINDOWS\SYSTEM\MFC40D.DLL'
   Loaded symbols for 'C:\WINDOWS\SYSTEM\MSVCR40D.DLL'
   Memory Leak detected...etc

I'm unsure of the nature of the error though.

-- Corey

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1308084
As I said - make this a new question - I cannot keep paying points to come in here.  And I cannot answer it until you open a new question.

Don't just ask the same thing under the same question heading.

Then I can tell you what your problem is and how to fix it.

0
 
LVL 3

Expert Comment

by:jaba
ID: 1308085
Well. Using GetDocument() method from destructor isnt correct. Because in this time CDocument object already deleted and m_pDoc member pointer of CView isnt valid. You have to remove you objects in CDocument::DeleteContents method.

P.S. RONSLOW, your comments to my answers is incorrect. Dont do it, pls.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1308086
What are you on about Jaba - I haven't made ANY comments about your answers.  This is the second time you've had a go at me ... we are trying to help someone here.

In fact we both put up similar comments, we both suspected that his constructor was wrong and simultaneously put up similar answers.

But I don't believe that is the problem - Corey still has the same problem.

BTW, Corey, my email is Roger_Onslow@compsys.com.au if you'd like to discuss this via e-mail instead, there are a few issues here and unless you either e-mail me or start a new question I cannot really continue trying to help you.  Actually, the best thing to do is both - start a new thread and e-mail me so I know that it is there.

Roger

mailto:Roger_Onslow@compsys.com.au

0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
repeatEnd java challenge 42 83
how do i create updater to My Activex application? 3 74
Replacement selected text 2 47
sameEnds challenge 3 106
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

708 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now