【问题标题】:App Crashes with Segmentation Fault when using mysimplebook->GetPageCount() wxWidgets使用 mysimplebook->GetPageCount() wxWidgets 时应用程序因分段错误而崩溃
【发布时间】:2021-09-08 02:41:36
【问题描述】:

您好,我正在使用 wxWidgets 创建一个简单的应用程序。但是,当您单击屏幕上的黑色按钮时,示例应用程序(如下所示)会崩溃。仅当您从 onClick() 事件处理程序中添加语句 mySimplebook->GetPageCount() 时,应用程序才会崩溃。如果我从 onClick() 内部删除上述语句的使用,则应用程序不会崩溃。此外,在 MySimplebook 构造函数中使用上述语句也不会导致应用程序崩溃。只有当我在 onClick() 处理程序中使用mySimplebook->GetPageCount(); 时,程序才会崩溃。否则,如果您从 onClick() 处理程序中省略此语句,则程序可以正常工作。我拥有的完整可重现代码如下:

mysimplebook.cpp

MySimplebook::MySimplebook(wxFrame *m_parentWindow, int id): wxPanel(m_parentWindow, id)
{
    wxBoxSizer *mainBoxsizer = new wxBoxSizer(wxVERTICAL);
    CustomButton *button = new CustomButton(this, wxID_ANY);
    mainBoxsizer->Add(button, 1, wxEXPAND, 0);
    mySimplebook = new wxSimplebook(this, wxID_ANY);

    First_Page *firstPage = new First_Page(mySimplebook);
    mySimplebook->AddPage(firstPage, "Input", false);
    
    mainBoxsizer->Add(mySimplebook, wxSizerFlags(1).Expand());
    /*program doesn't crashes here*/
    std::cout<<"Pages inside constructor: "<<(mySimplebook->GetPageCount())<<std::endl;
    this->SetSizer(mainBoxsizer);
}
void MySimplebook::onClick(wxMouseEvent &event)
{
    std::cout<<"event received from button"<<std::endl;
    //program creashes here
    std::cout<<"pagecount inside onclick:"<<(mySimplebook->GetPageCount())<<std::endl;
}

custombutton.cpp

CustomButton::CustomButton(wxWindow *parent, int id):wxPanel(parent, id)
{
    SetBackgroundColour(wxColour(0,0,0));
    Connect(wxEVT_LEFT_UP, wxMouseEventHandler(MySimplebook::onClick));
    
}

当我单击按钮时程序崩溃。我的问题是:

  1. 如何解决此运行时崩溃问题?
  2. 为什么会发生这种崩溃?我以后应该如何避免它,比如使用bind。或者我的代码的哪一部分应该更改以及如何更改?

这是回溯:

程序在控制台上崩溃并显示以下内容:

Pages inside constructor: 1
event received from button
Segmentation fault (core dumped)

PS:我知道问题很可能与Connect() 通话有关。但不知道如何解决/纠正它。

【问题讨论】:

  • 不确定您要实现什么,但您需要分享AddPage 实现以及docs.wxwidgets.org/3.0/classwx_notebook.html
  • 如果没有合适的minimal reproducible example,就很难说什么。另外,您是否尝试过使用调试器来捕获崩溃,以验证它发生在您认为发生的地方?
  • @macroland AddPage() 是一个预定义的方法。这不是我编写的自定义方法。如何共享 AddPage() 的实现文件?能说清楚一点吗?
  • @JasonLiam,如果您发布所有内容的文本版本而不是屏幕截图,这将对每个人都有帮助。有些人是盲人,但仍然可以帮助解决问题。同时对 3 个不同的资源提出相同的问题也无济于事。请考虑仅在一个地方(从论坛或此处开始)进行操作,并在被询问时 - 将其发布到另一个地方。它只会扼杀你在网上(和这里)的声誉。
  • @Someprogrammerdude 问题似乎是当我使用CustomButton *button = new CustomButton(this, wxID_ANY); 创建CustomButton 时,“this”指针被复制到wxWindow parent 参数。现在父参数的值与我们原来的“this”指针不同了。现在,当控制流转到 onClick() 处理程序时,parent 的值被视为“this”指针的值,而不是“this”的原始值。你能判断这个问题是否可以轻松解决,或者我应该创建一个 CustomEvent 类,以便 customevent 可以向上传播并避免这个问题?

标签: c++ c++11 events event-handling wxwidgets


【解决方案1】:

解决方案是使用bind 而不是connect。除了在 custombutton.cpp 中使用 Connect() 调用,我们可以在 mysimplebook.cpp 中创建该按钮之后立即使用bind。所以修改语句后:

Connect(wxEVT_LEFT_UP, wxMouseEventHandler(MySimplebook::onClick));

button->Bind(wxEVT_LEFT_UP, &MySimplebook::onClick, this);

该程序有效。请注意,bind 语句就在 mysimplebook.cpp 中 CustomButton 的定义之后,无需在 custombutton 构造函数中使用它。

【讨论】:

  • 使用Bind()确实比使用Connect()更好,更不容易出错,但您仍然需要了解您错误地使用了Connect(),因为您没有提供@987654329 @ 指针,它需要调用它的 onClick() 方法,而不是看似说“哦,Connect 不起作用”。
  • 是的,我也想通了。我正在处理的实际项目的问题是 MySimplebook 类具有 #include"custombutton.h" 而 Custombutton 类具有 #include"mysimplebook.h" 所以它会导致循环依赖。我改变了项目的结构,就像现在 Custombutton 类不依赖于 MySimplebook 类一样。我想,由于结构的这种变化,我仍然可以使用 Connect() ,但这次也将指向 MySimplebook 的指针传递给 Connect 调用。但 Bind() 更面向现代 C++,所以我将使用 bind,因为我已经在使用其他 C++ 11 特性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
相关资源
最近更新 更多