Stardust Sauce
Stardust Sauce

Reputation: 41

Why am I encountering a Segmentation Fault when accessing Inherited Variables from a wxWidgets event?

I'm currently developing an app in C++ using wxWidgets. I currently have a class ArchetypeTable which derives from the wxListCtrl class, and it has a number of functions which I have declared that are meant to be used by the MainWindow class's Event Handlers. However, I'm experiencing an unusual behavior: Whenever I try to access any of the wxListCtrl's functions or members,that is, the variables and members which I have inherited in my ArchetypeTable class, I encounter a Segmentation Fault. This only occurs when I attempt access an inherited function or member from within the body of the Event Handler function, or from within any function called within those Event Handlers. These functions work fine in other contexts, such when called from within the ArchetypeTable or the MainWindow's constructor.

Below is my code. I've trimmed out some irrelevant pieces.

main-window.cpp

#include "main-window.h"
#include "archetype-table.h"

MainWindow::MainWindow(const wxString& title, int width, int height)
  : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxSize(width, height)) {
  m_MainPanel = new wxPanel(this);
  

  m_ClassDropdown = new wxComboBox(m_MainPanel, wxID_ANY, wxT("Select a class..."), wxDefaultPosition, wxDefaultSize, GetClassList(), wxCB_SORT | wxTE_PROCESS_ENTER);

  ArchetypeTable* m_ArchetypeTable = new ArchetypeTable(m_MainPanel);

  m_TransferButton = new wxButton(m_MainPanel, wxID_ANY, "Select an Archetype...");

  // Apply Sizers to all objects
  wxBoxSizer* rootSizer = new wxBoxSizer(wxHORIZONTAL);
  rootSizer->Add(m_MainPanel, 1, wxEXPAND | wxALL, 10);
  rootSizer->SetSizeHints(this);
  this->SetSizerAndFit(rootSizer);

  wxFlexGridSizer* mainSizer = new wxFlexGridSizer(1, 5, 5);
  mainSizer->AddGrowableCol(0);
  mainSizer->AddGrowableRow(1);
  mainSizer->Add(m_ClassDropdown, 0, wxALIGN_RIGHT);
  mainSizer->Add(m_ArchetypeTable, 1, wxEXPAND);
  mainSizer->Add(m_TransferButton, 0, wxALIGN_RIGHT);
  mainSizer->SetSizeHints(this);
  m_MainPanel->SetSizerAndFit(mainSizer);

  // Bind all events
  m_TransferButton->Bind(wxEVT_BUTTON, &MainWindow::OnTransferButtonClick, this);

  // Center the window on the screen.
  Centre();
}

void MainWindow::OnTransferButtonClick(wxCommandEvent &event) {
  // Problematic function. This call causes a Segmentation Fault.
  m_ArchetypeTable->ClearAll();
}

archetype-table.cpp

#include "archetype-table.h"
#include "pf-class-list.h"

ArchetypeTable::ArchetypeTable(wxWindow* parent) : wxListCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT) { }

void ArchetypeTable::PopulateTable(wxCommandEvent &event) {
  // Do stuff
}

Upvotes: 1

Views: 201

Answers (1)

Stardust Sauce
Stardust Sauce

Reputation: 41

As pointed out by WhozCraig, the source of this issue was that the ArchetypeTable that this was being performed on had been declared both as a class variable and then subsequently hidden by a second declaration in the Constructor. The table created is going out of scope, and so when the function calls are made on the underlying, undeclared object, undefined behavior ensues.

Upvotes: 3

Related Questions