Invalid wxFrame pointer address thrown during initialization Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
dark.tempest360
In need of some credit
In need of some credit
Posts: 7
Joined: Fri Jun 15, 2018 4:24 pm

Invalid wxFrame pointer address thrown during initialization

Post by dark.tempest360 »

So I've been creating a sudoku app for my first wxWidgets project and have come into a roadblock. I have been previously implementing a "Pen Mode" switch internally baked into the individual components. However, I wanted to expose this option into the menu bar.

To read/write into the menu option, I passed the pointer of the wxFrame (MainFrame) during wxFrame initialization to an internally maintained class meant to hold preferences and settings. I then used GetMenuBar() to get the menu bar and get the values of options exposed in the menu bar itself when needed. However, it results to a segmentation fault. Using wxGetTopLevelWindow() to the control component calling one of my preference writing functions SudokuControl::TogglePencilMode proves that I'm stroring an invalid wxFrame pointer address (and that subsequent calls to wxGetTopLevelWindow() when the function is called again proves that the correct address doesnt change).

So, at what point should I get a pointer to the main wxFrame?

(Sorry this is so long.. I posted a question last time and was requested code. This is more or less part of the actual code im currently writing)

main.cc

Code: Select all

MainFrame::MainFrame() : wxFrame(NULL, wxID_ANY, "Hello World"){
	wxMenu *menuFile = new wxMenu;
	menuFile->Append(ID_Hello, "&Hello...\tCtrl-H", "Help string");
	menuFile->AppendSeparator();
	menuFile->Append(wxID_EXIT);

	wxMenu *menuInput = new wxMenu;
	menuInput->AppendCheckItem(ID_PencilMode, "&Pen Mode\tP");
	menuInput->Check(ID_PencilMode, true);

	wxMenu *menuHelp = new wxMenu;
	menuHelp->Append(wxID_ABOUT);

	wxMenuBar *menuBar = new wxMenuBar;
	menuBar->Append(menuFile, "&File");
	menuBar->Append(menuInput, "&Input");
	menuBar->Append(menuHelp, "&Help");

	SetMenuBar(menuBar);

	CreateStatusBar();
	SetStatusText("Test app for wxWidgets :)");


	Bind(wxEVT_MENU, &MainFrame::OnHello, this, ID_Hello);
	Bind(wxEVT_MENU, &MainFrame::OnAbout, this, wxID_ABOUT);
	Bind(wxEVT_MENU, &MainFrame::OnExit, this, wxID_EXIT);

	wxPanel *panel = new wxPanel(this, wxID_ANY);
	wxSizer *grid = new wxGridSizer(3);
	for(int x = 0; x < 3; x++){
		for(int y = 0; y < 3; y++){
			grids[x][y] = new SudokuGrid(panel, wxPoint(x,y), wxSize(3, 3));
			grid->Add(grids[x][y], wxSizerFlags(0).Center().Border());
		}
	}
	panel->SetSizer(grid);
	panel->SetBackgroundColour(wxColour(0, 0, 0));
	wxSizer *frameSizer = new wxGridSizer(1);
	frameSizer->Add(panel, wxSizerFlags(0).Center());
	SetSizerAndFit(frameSizer);

	sudokuControl.sss(wxGetTopLevelParent(this));
}

void MainFrame::OnExit(wxCommandEvent& WXUNUSED(event)){
	Close(true);
}

void MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event)){
	wxMessageBox("This is a work in progress sudoku app", "About this program", wxOK|wxICON_INFORMATION);
}

void MainFrame::OnHello(wxCommandEvent& WXUNUSED(event)){
	wxLogMessage(wxT("Hiiiii!"));
}

void MainFrame::hi(){
	wxLogMessage(wxT("oh hey there"));
}
main.h

Code: Select all

class MainApp : public wxApp{
	public:
	virtual bool OnInit();
};

class MainFrame : public wxFrame{
	public:
	MainFrame();
	void hi();

	private:
	SudokuGrid *grids[3][3];
	void OnHello(wxCommandEvent& WXUNUSED(event));
	void OnExit(wxCommandEvent& WXUNUSED(event));
	void OnAbout(wxCommandEvent& WXUNUSED(event));
};
control.cc

Code: Select all

void SudokuControl::TogglePencilMode(wxWindow *window){
    //wxMessageBox("toggling");
    ((MainFrame*) menuPencilMode)->hi();
    wxFrame *fr = (wxFrame*)wxGetTopLevelParent(window);
    if( fr != menuPencilMode){
        wxMessageBox("they are unequal");
        menuPencilMode = (MainFrame*) fr;
        //((MainFrame*) menuPencilMode)->hi();
    }
    wxMenuBar* menu = fr->GetMenuBar();
    //wxMessageBox("toggle middle");
    menu->Check(ID_PencilMode, !(menu->IsChecked(ID_PencilMode)));
    //wxMessageBox("toggle end");
}

bool SudokuControl::PencilMode(){
    //wxMessageBox("tilted try");
    return menuPencilMode->GetMenuBar()->IsChecked(ID_PencilMode);
    //wxMessageBox("tilted done");
}

void SudokuControl::sss(wxWindow *topLevel){
    menuPencilMode = (wxFrame*) topLevel;
    ((MainFrame*) menuPencilMode)->hi();
}
User avatar
doublemax
Moderator
Moderator
Posts: 19163
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Invalid wxFrame pointer address thrown during initialization

Post by doublemax »

Code: Select all

sudokuControl.sss(wxGetTopLevelParent(this));
wxGetTopLevelParent(this) will probably return NULL, as "this" has no parent. Just calling sudokuControl.sss(this) should do the trick.

The whole purpose of the "sudokuControl" class is a little unclear though.
Use the source, Luke!
dark.tempest360
In need of some credit
In need of some credit
Posts: 7
Joined: Fri Jun 15, 2018 4:24 pm

Re: Invalid wxFrame pointer address thrown during initialization

Post by dark.tempest360 »

neither returns a nullptr and is useable within SudokuControl::sss() but is unusable once reused in a different function (segmentation fault).
sudokuControl is of class SudokuControl and is a static variable that will hold all user preferences in a neat class that should handle loading required settings in one place.
User avatar
doublemax
Moderator
Moderator
Posts: 19163
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Invalid wxFrame pointer address thrown during initialization

Post by doublemax »

There must be another reason for the crash.
sudokuControl is of class SudokuControl and is a static variable
Are you sure there is only one instance of it? Maybe you're accessing another, uninitialized version later.
Use the source, Luke!
Nunki
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 235
Joined: Fri Sep 14, 2012 8:26 am
Location: Kontich, Belgium

Re: Invalid wxFrame pointer address thrown during initialization

Post by Nunki »

Hi dark....
You don't have to apologise, you tried to give us as much information as you could. And in that way we can actually help you.

There is some code above your main frame, isn't it ? The basic framework you can find on several wxWidgets sites as the example to start building your application.

Code: Select all

IMPLEMENT_APP(tcQuill)
IMPLEMENT_CLASS(tcQuill,wxApp)

// Event table
BEGIN_EVENT_TABLE( tcQuill, wxApp )
END_EVENT_TABLE()



bool tcQuill::OnInit(void)
from within this OnInit method you create your mainframe, and that's where I would keep a variable to your mainframe.

Code: Select all

 rApp.pMainWindow = new tcBaseFrame(sApp,nX,nY,nWidth,nHeight);
 SetTopWindow(rApp.pMainWindow);
 rApp.pMainWindow->Show(true);
 rApp.pMainWindow->Update();
 rApp.pMainWindow->Refresh();
Hope this helps you on your way,
regards,
Nunki
dark.tempest360
In need of some credit
In need of some credit
Posts: 7
Joined: Fri Jun 15, 2018 4:24 pm

Re: Invalid wxFrame pointer address thrown during initialization

Post by dark.tempest360 »

doublemax wrote:]Are you sure there is only one instance of it? Maybe you're accessing another, uninitialized version later.
I wasn't used to programming in c++ with multiple source files and headers. It was in fact what you said. I got it fixed :) thaaanks :)