Код в порядке, но пример слишком неполный, чтобы сказать, что не так. Некоторые вещи, которые я бы предложил:
Добавить распечатки к деструктору и конструктору каждого класса:
Game::Game() { cerr << this << " Game::Game" << endl; }
Game::Game(Game const&) { cerr << this << " Game::Game(Game const&)" << endl; }
Game::~Game() { cerr << this << " Game::~Game" << endl; }
bool Game::some_function() { cerr << this << " Game::some_function()" << endl; ... }
Это покажет:
- Указатели нулевых объектов.
- Плохие / удаленные указатели классов.
Во-вторых, для отладки я настоятельно рекомендовал бы отправлять распечатки в cerr вместо cout. cout обычно буферизуется (для эффективности) перед выводом, cerr - нет (по крайней мере, раньше). Если ваша программа завершает работу без выполнения своих обработчиков ошибок, at_exit и т. Д., Вы с большей вероятностью увидите вывод, если он небуферизован и распечатан немедленно.
В-третьих, если ваши объявления классов находятся в заголовке, определения классов находятся в одном файле cpp, а код, который использует класс в другом, вы можете получить такой вид сбоя, если ни один из файлов cpp не был перекомпилирован после того, как вы изменили заголовок.
Некоторые другие возможности:
- переполнение стека: вы распределили много памяти в стеке из-за глубокой рекурсии или выделяете объекты, содержащие большие массивы данных, в качестве локальных переменных (то есть не созданы или кучи с новыми или malloc))
- поврежденный класс vtable (обычно это возможно только из-за ошибок зависимостей в ваших инструментах сборки),
- поврежденный указатель vtable объекта: возможно из-за неправильного использования указателей: использование указателей на удаленную память или неправильная запись по используемому адресу. Маловероятно в вашем примере, потому что нет виртуальных функций.
- сохранение указателя или ссылки на объект, размещенный в стеке, который был удален: приведенный выше код распечатки раскроет этот случай.