wxWidgets:关闭自定义模式对话框时出现内存错误

时间:2014-08-30 15:00:03

标签: c++ exception memory wxwidgets

我已阅读this,但我仍然不明白我的代码错误。

这里是bmNewFromImageDialog.h,即扩展wxDialog的类。

#ifndef BMNEWFROMIMAGEDIALOG_H
#define BMNEWFROMIMAGEDIALOG_H

#include "./../utils/includer.h" // includes a bunch of wx-related files
class bmNewFromImageDialog : public wxDialog {
public:
    wxBoxSizer *mainVBox, *flagHBox, *OKCancelHBox;
    wxStaticBox *flagsSBox;
    wxButton *OKButton, *cancelButton;
    wxRadioButton *GT0RadioButton;

    bmNewFromImageDialog() {}
    bmNewFromImageDialog(wxWindow *parent);

    void init();
};

#endif

这里是bmNewFromImageDialog.cpp

#include "./bmNewFromImageDialog.h"
#include "./../utils/includer.h"

bmNewFromImageDialog::bmNewFromImageDialog(wxWindow *parent) : wxDialog(parent, -1, wxT("new image..."), wxDefaultPosition, wxDefaultSize) {
    init();
}

void bmNewFromImageDialog::init() {
    mainVBox = new wxBoxSizer(wxVERTICAL);
    flagHBox = new wxBoxSizer(wxHORIZONTAL);
    OKCancelHBox = new wxBoxSizer(wxHORIZONTAL);

    flagsSBox = new wxStaticBox(this, -1, wxT("Color flags"), wxPoint(0, 0), wxDefaultSize);
    GT0RadioButton = new wxRadioButton(this, -1, wxT(">0: 3 channels"), wxPoint(0, 0));
    flagsSBox->AddChild(GT0RadioButton);
    flagHBox->Add(flagsSBox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);

    OKButton = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(100, 40));
    cancelButton = new wxButton(this, wxID_CANCEL, wxT("cancel"), wxDefaultPosition, wxSize(100, 40));
    OKCancelHBox->Add(OKButton, 1);
    OKCancelHBox->Add(cancelButton, 1, wxLEFT, 5);

    mainVBox->Add(flagHBox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);
    mainVBox->Add(OKCancelHBox, 0, wxALIGN_CENTER | wxBOTTOM, 10);
    SetSizer(mainVBox);
    Center();
}

这就是我在代码中使用对话框的方式:

bmNewFromImageDialog *newDialog = new bmNewFromImageDialog(this);
newDialog->ShowModal();
delete newDialog;

当我关闭/单击确定/单击bmNewFromImageDialog上的取消时,我在运行时经常遇到未处理的内存异常错误。我该如何解决这个问题?

修改

@sir-digby-chicken-caesar我尝试了.Destroy()和堆栈解决方案,但仍然存在同样的错误:

enter image description here

2 个答案:

答案 0 :(得分:0)

这个区块:

bmNewFromImageDialog *newDialog = new bmNewFromImageDialog(this);
newDialog->ShowModal();
delete newDialog;

应改为:

bmNewFromImageDialog *newDialog = new bmNewFromImageDialog(nullptr);
newDialog->ShowModal();
newDialog->Destroy();

永远不要在wx小部件类上调用delete。如果您需要取消分配窗口小部件,请将其从父层次结构中删除,将其与使用它的任何分级器分离,然后调用Destroy();

修改

正如用户VZ和wxWidgets documentation所指出的,模态对话框是少数几个不需要在堆上创建的wx小部件类之一。因此,您可以在堆栈上创建对话框,并在对象超出范围后让析构函数处理为您清理:

bmNewFromImageDialog newDialog = bmNewFromImageDialog(nullptr);
newDialog.ShowModal();

答案 1 :(得分:0)

flagsSBox = new wxStaticBox(this, -1, wxT("Color flags"), wxPoint(0, 0), wxDefaultSize);
GT0RadioButton = new wxRadioButton(this, -1, wxT(">0: 3 channels"), wxPoint(0, 0));
flagsSBox->AddChild(GT0RadioButton);
//         ^^^^^^^^ this looks very wrong

该调用未记录,并在头文件中标记为“主要实现”。除非你真的知道自己在做什么,否则不要使用它。

如果您只是创建GT0RadioButton并将flagsSBox作为其父级,则看起来您的代码应该有效(删除AddChild调用)。

同时查看wxStaticBoxSizer