K
K
Kirill Zhilyaev2018-05-20 01:47:38
C++ / C#
Kirill Zhilyaev, 2018-05-20 01:47:38

Reasons for memory leaks?

I've been struggling with memory leaks for 2 weeks now. There is a polymorphic class C (Inherits B and B in turn A). There is a vector with an instance of A, both classes B and classes C are entered into it. There are no problems with classes B (all OK are entered and taken out). When the program works with C classes, the bacchanalia begins. RAM is running out. At first I thought: "Well, I forgot to delete something somewhere." I created a map in which I recorded the calls of constructors and destructors. Everything is okay.
Later I read about the virtual destructor. I set myself a virtual destructor, but the situation did not improve.
Valgrid did not show anything intelligible.

spoiler
lina.funroyale.com/ghost.rar - source. CGameBase is the topmost class in the hierarchy. CGame is the second. CGamePetri is a problematic third. CpetroAction is described in statspetri.
lina.funroyale.com/leak.xml - valgrind log

Answer the question

In order to leave comments, you need to log in

3 answer(s)
J
jcmvbkbc, 2018-05-20
@jcmvbkbc

There is a vector with instances of A, both classes B and classes C are entered into it.

It suggests that your objects are cut off by class A, i.e., perhaps what happens is not at all what you expected.
Download and show.

V
Vitaly, 2018-05-20
@vt4a2h

Opened virtual destructors? Perfectly! It's time to open smart pointers. A simple rule for beginners: no explicit new and delete at all, everything is passed and returned everywhere using smart pointers (const references to them). Then you can read / watch Sutter, and start transmitting something via links or bare pointers. But this is the next level.

A
Ariox41, 2018-05-20
@Ariox41

Error in CGamePetri destructor:

for( vector<CPetriAction *> :: iterator i = m_Messages.begin(); i != m_Messages.end();  )
{
     delete *i;
     m_Messages.erase( i );
}

When an eraseiterator is called, it becomes invalid. In practice, the elements 0, 2, 4 ... in the first half of the vector are most likely removed, because when the null element is removed, the first becomes null, the second becomes the first, and the iterator goes to the new first element, which used to be the second. Solved easily:
for( vector<CPetriAction *> :: iterator i = m_Messages.begin(); i != m_Messages.end();  )
{
     delete *i;
}
//m_Messages.clear(); // - в данном случае смысла нет, т.к. это деструктор

Or even easier:
for(auto& ptr:  m_Messages){
   delete ptr;
}

If m_Messagesstored unique_ptr- then this is not necessary, the objects will be deleted automatically in the vector destructor.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question