My program keeps crashing when I close the frame. I've narrowed the cause down to two lines of problematic code, but I'm not sure why they're crashing. Here's some of my code:
TetrisFrame.cpp
TetrisFrame::TetrisFrame()
: wxFrame(0, wxID_ANY, "Tetris")
{
statusController_ = new StatusController;
statusController_->setModel(new Statuses);
statusController_->addView(this);
tetrisController_ = new TetrisController;
tetrisController_->setStatusController(statusController_.get()); // Problem one
tetrisController_->setModel(new TetrisModel);
tetrisController_->addView(new Board(this)); // Problem two
}
TetrisFrame class private member variables:
wxSharedPtr<StatusController> statusController_;
wxSharedPtr<TetrisController> tetrisController_;
StatusController class private section:
typedef wxSharedPtr<TetrisFrame> ViewPtr;
wxSharedPtr<Statuses> model_;
std::vector<ViewPtr> views_;
Board class private member variables:
wxSharedPtr<TetrisController> controller_;
relevant TetrisController functions:
void TetrisController::setStatusController(
StatusController* statusControllerPtr)
{
statusController_ = statusControllerPtr;
}
void TetrisController::addView(Board* viewPtr)
{
views_.push_back(ViewPtr(viewPtr));
viewPtr->setControlller(this);
}
Oddly enough problem two wasn't crashing the program until I fixed another problem that was crashing the program. What's wrong with my code?
Keep in mind that wxWidgets does its own form of memory management for widgets. So if you are dynamically allocating the memory for a widget-type, and you then pass the address of that widget to an object that can call delete
on it while the parent of that widget is designated by the wxWidgets run-time to destroy that widget when the parent widget is destroyed, then you're going to run into a case of double-deletion, or a case where the parent still thinks the child widget is a valid object when it's not. A shared-pointer type will basically "own" an object ... so make sure that when you dynamically allocate an object and pass it to a shared-pointer type that you are not inadvertently making the pointer "owned" by two different memory-reclaiming pathways.