Здравствуйте, rg45, Вы писали:
R>И тебя не смущает, что он появился на форуме на 13 лет раньше тебя?
Да какая разница? Код явно низкого качества.
Вот смотрите:
void CDynamicMesh::removeBlock(eing::graphic::world::CBlock *block)
{
m_blocks.remove(block);
if(block == m_parentBlock)
{
m_parentBlock = m_blocks.empty() ? nullptr : m_blocks.front();
}
recalculate();
}
void CDynamicMesh::recalculate()
{
if(m_blocks.size() && m_parentBlock)
{ ... }
}
О чём говорит проверка
if(m_blocks.size() && m_parentBlock) ? Я вижу 4 варианта:
1)
m_blocks.size() и
m_parentBlock — две независимые переменные
2) Sheridan не пользуется assert'ами
3) оптимизация обращения к первому элементу списка
4) проблемы в другом месте кода
судя по коду в removeBlock пункт 1 отпадает. Значит пункты 2-4 реализуются либо совместно, либо по отдельности. Скорее всего m_parentBlock вообще не нужен — это просто первый элемент из списка.
Теперь смотрим на ~CBlock():
40 CBlock::~CBlock()
41 {
42 { do { eing::CSingleTone::instance()->logger()->start() << "[Debg] {" << eing::CSingleTone::instance()->debug_counter++ << "} " << std::string(std::string("Point" " in file " __FILE__ " at line " __LINE__ " in method ") + std::string(__func__));; eing::CSingleTone::instance()->logger()->stop();; } while(false); };
43 if(m_dynamicMesh)
44 {
45 m_dynamicMesh->removeBlock(this);
46 if(m_dynamicMesh->empty())
47 {
48 delete m_dynamicMesh;
49 m_dynamicMesh = nullptr;
50 }
51 }
52 m_worldBlock->removeGraphicsBlock();
53 m_worldBlock = nullptr;
54 { do { eing::CSingleTone::instance()->logger()->start() << "[Debg] {" << eing::CSingleTone::instance()->debug_counter++ << "} " << std::string(std::string("Point" " in file " __FILE__ " at line " __LINE__ " in method ") + std::string(__func__));; eing::CSingleTone::instance()->logger()->stop();; } while(false); };
55 }
Вас ничего не смущает? Зачем занулять члены класса в деструкторе? Такой приём используют либо новички, либо это хак, который защищает код от падения при обращении к уже разрушенному объекту. (Ну или это статические члены класса, что вряд ли)
Почему m_dynamicMesh — dynamic? Значит где-то есть статик? Т.е. можно предположить, что вызывается delete для переменной не заказанной по new.
Предположим, что m_dynamicMesh — это указатель на CDynamicMesh.
Тогда смотрите:
Если кто-то удаляет объект на который указывает m_dynamicMesh извне деструктора ~CBlock, то
CDynamicMesh::~CDynamicMesh()
{
EING_LOG_DBG_POINT;
if(m_dynamicModel) { EING_ST->graphic()->physicsWorld()->RemoveCachedGeometry(m_dynamicModel); } // Это urho3d, не смотрел что там происходит
delete m_vertexBuffer;
delete m_indexBuffer;
delete m_geometry;
m_podElements.Clear();
if(m_dynamicModel) { delete m_dynamicModel; } // Это urho3d объект, не мой
EING_LOG_DBG_POINT;
}
m_blocks никто не чистит и, соответственно, объекты типа CBlock никто не удаляет — это если предположить, что m_blocks имеет тип std::list<CBlock*>. мы получаем кучу ссылок на убитый объект и утечку памяти.
Если же предположить, что m_blocks — это такой список, который удаляет свои элементы при очистке, то получится ещё интереснее: после выполнения ~CDynamicMesh() начнётся выполнение серии деструкторов ~CBlock, которые попытаются удалить себя из списка находящегося в процессе очистки, а последний элемент ещё и удалит CDynamicMesh второй раз. Так или иначе — ничего хорошего.
Из всего этого следует, что объекты типа CDynamicMesh никогда сами не удаляются. Из этого следует, что на объекты CBlock указатели хранятся где-то снаружи CDynamicMesh и там же уничтожаются. Т.е. мы поняли архитектуру: элементы списка владеют своим списком. Они сами себя из списка удаляют, но добавляют их в список внешним образом:
void CDynamicMesh::addBlock(eing::graphic::world::CBlock *block)
{
m_blocks.push_back(block);
recalculate();
}
Вы видите, чтобы block->m_dynamicMesh устанавливался в this в этом методе? Не удивлюсь, если окажется, что recalculate() проходит по списку элементов им устанавливает каждому элементу m_dynamicMesh в this.
Не, ну очевидно, что это код опытного хардкорщика презирающего смарт поинтеры и точно знающего где и что удаляется.