C++ wxListBox-分段故障

C++ wxListBox-分段故障,c++,linux,segmentation-fault,wxwidgets,C++,Linux,Segmentation Fault,Wxwidgets,几个小时以来,我一直在努力学习如何从wxWidgets使用wxListBox。我把我的“应用程序”建立在官方的基础上,但我不能让它工作,即使我的代码和最初的代码没有太大的不同 我想在wxListBox中添加一个新项目,但得到的是分段错误。这是我的密码: class CWindow : public wxFrame { wxBoxSizer *hbox, *vbox; wxListBox *list; wxButton *

几个小时以来,我一直在努力学习如何从wxWidgets使用wxListBox。我把我的“应用程序”建立在官方的基础上,但我不能让它工作,即使我的代码和最初的代码没有太大的不同

我想在wxListBox中添加一个新项目,但得到的是分段错误。这是我的密码:

class CWindow : public wxFrame {
    wxBoxSizer      *hbox, *vbox;
    wxListBox           *list;
    wxButton            *btnAdd, *btnRemove;

public:
    CWindow(int w = 640, int h = 480) : wxFrame(NULL, -1, wxT("Test"), wxDefaultPosition, wxSize(w, h)) {
        list = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(w-100, h));
        btnAdd = new wxButton(this, -1, wxT("Add"));
        btnAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnNew);
        btnRemove = new wxButton(this, -1, wxT("Remove"));

        vbox = new wxBoxSizer(wxVERTICAL);
        vbox->Add(btnAdd, 1, wxALL | wxEXPAND, 0);
        vbox->Add(btnRemove, 1, 0, 0);

        hbox = new wxBoxSizer(wxHORIZONTAL);
        hbox->Add(list, 1, 0, 0);
        hbox->Add(vbox, 0, 0, 0);

        SetSizer(hbox);
    }

    void OnNew(wxCommandEvent &event) {
        wxString str = wxGetTextFromUser(wxT("New item:"));
        if (str.Len() > 0) list->InsertItems(1, &str, 0); //this line is suspected of causing segfault
    }
};
知道是什么引起了我的问题吗

附:教程示例运行良好,因此不可能出现库错误

编辑: gdb调试器报告以下情况:

0x00007ffff7a8e492 in wxListBoxBase::InsertItems(unsigned int, wxString const*, unsigned int) () from /usr/lib/x86_64-linux-gnu/libwx_gtk2u_core-2.8.so.0
编辑2:更多gdb转储 之前:


从您发布的调试输出来看,您的问题不是使用listbox,而是使用wxFrame。我猜您在wxApp实例中搞乱了wxFrame的处理


我建议您重新开始,从最小的示例开始,然后逐步构建应用程序。

多亏了许多建议,我才成功地解决了这个问题。这是由于直接将按钮连接到功能上造成的。似乎每个按钮都必须有相应的标识符

所以这是错误的:

button = new wxButton(this, wxID_ANY, wxT("label"));
(...)
button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnClick);
这很好:

button = new wxButton(this, EVT_OnClick, wxT("label"));
(...)
Connect(EVT_OnClick, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnClick);

你从哪里得到segfault?@H2CO3:只要我在按下New按钮后输入文本。@Robin92-我想H2CO3会询问调试器报告它的行号。你是凭直觉添加了评论还是调试器说了什么?@Flexo我不使用调试器。当我注释掉
if(str.Len()>0)list->InsertItems(1,&str,0)segfault不会出现。这不是gdb最有趣的输出行-请尝试向上查看几帧到最近的代码行。打印
列表的值
——我猜你打那个电话时它是
NULL
。(可能不是,可能是无效指针)好的,在行上放置一个断点,并检查列表指针的值是否合理。问题是这是一个最小的示例。除了从wxApp继承的MyApp类之外,我没有其他代码。这门课不能搞砸,是吗?从调试器输出中,我了解到
$1=(wxListBox*)0x0
意味着我的列表变量指向NULL。好的,那么为什么
list->Append(“第一项”)
在构造函数中工作呢?您是从发行版中提供的最小样本开始的吗?看起来确实不像你。在示例中,主框架名为MyFrame。调用主框架CWindow不是惯用的wxWidgets编码。这是一个非常糟糕的想法。您应该将控件ID与事件ID分开。请查看发行版中提供的示例,并将您的应用程序建立在这些示例的基础上,直到您了解如何使用wxWidgets idiom.bad进行操作?这就是在所提到的教程中如何做到这一点的例子!不是这样。请看教程。您将看到为按钮和其他小部件选择的ID没有使用事件ID。例如ID_RENAME.BTW,您提到的教程是由一个叫Jan Bodnar的人编写的,他是AFAIK,没有以任何官方身份与wxWidgets连接。我建议您看看wxWidgets发行版附带的示例应用程序-那里的代码与许多使用wxWidgets的人使用的代码更相似。我真的希望我永远不必维护您编写的任何代码。
button = new wxButton(this, EVT_OnClick, wxT("label"));
(...)
Connect(EVT_OnClick, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) &CWindow::OnClick);