kirill_782
@kirill_782
Днем я Маринетт

Причины утечек памяии?

Уже 2 недели бьюсь над утечками в памяти. Есть полиморфный класс C (Наследует B а B в свою очередь A). Есть вектор с экземпляроми A в него заносятся как классы B так и классы C. С классами B проблем нет (заносятся и выносятся все ОК). Когда программа работает с классами C то начинается вакханалия. Уходит RAM. Первое время думал: "ну забыл где то что то удалить". Создал map в который записывал вызоыв конструкторов и деструкторов. Все в норме.

Позже прочитал про виртуальный деструктор. Поставил себе виртуальный деструктор, но ситуация не улучшилась.

Valgrid внятного ничего не показал.

spoiler
lina.funroyale.com/ghost.rar - соурс. CGameBase самый верхний класс в иерархии. CGame - второй. CGamePetri - проблемный третий. CpetroAction описан в statspetri.
lina.funroyale.com/leak.xml - лог с valgrind
  • Вопрос задан
  • 138 просмотров
Пригласить эксперта
Ответы на вопрос 3
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Есть вектор с экземплярами A в него заносятся как классы B так и классы C.

Подсказывает, что объекты твои обрезаются по классу A, т.е., возможно, происходит совсем не то, что ты ожидал.
Если нужен код могу загрузить в репозиторий.

Загружай и показывай.
Ответ написан
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Открыли виртуальные деструкторы? Прекрасно! Пришло время открыть умные указатели. Простое правило для новичков: вообще никаких явных new и delete, всё везде передаётся и возвращается с помощью умных указателей (конст ссылок на них). Потом уже можно почитать/посмотреть Саттера, и начать что-то передавать по ссылкам или голым указателям. Но это уже следующий уровень.
Ответ написан
@Ariox41
В деструкторе CGamePetri ошибка:

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


Когда вызывается erase итератор становится невалидным. На практие скорее всего удаляются элементы 0, 2, 4 ... в первой половине вектора, т.к. когда удаляется нулевой элемент - первый становится нулевым, второй первым, и итератор переходит на новый первый элемент, который раньше был вторым. Решается легко:
for( vector<CPetriAction *> :: iterator i = m_Messages.begin(); i != m_Messages.end();  )
{
     delete *i;
}
//m_Messages.clear(); // - в данном случае смысла нет, т.к. это деструктор


Или еще проще:
for(auto& ptr:  m_Messages){
   delete ptr;
}


Если в m_Messages хранить unique_ptr - тогда и этого не нужно, объекты удалятся автоматически в деструкторе вектора.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы