析构函数 Qt QDialog 中的分段错误

Segmentation fault in destructor Qt QDialog

当我关闭 qdialog_search 的父窗口(主窗口)时,qdebugger 证明 qdialog_search 析构函数中存在段错误。 qdialog_search 是从 QDialog 派生的(也许这就是问题所在)。 这是代码:

//.h
#ifndef QDIALOG_SEARCH_H
#define QDIALOG_SEARCH_H
#include <QDialog>
#include <QVBoxLayout>
#include <QTabWidget>
#include <QDebug>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
class QDialog_search: public QDialog{
private:
QVBoxLayout* main;
QTabWidget* tab;
// id
QWidget* search_id;
QVBoxLayout* id_l;
QLineEdit* id_line;
QPushButton* id_button;
// owner
QWidget* search_owner;
QVBoxLayout* ow_l;
QLineEdit* ow_line;
QPushButton* ow_button;
// destination
QWidget* search_dest;
QVBoxLayout* dest_l;
QLineEdit* dest_line;
QPushButton* dest_button;
public:
QDialog_search(QWidget* parent=0);
void buildSearchId();
void buildSearchOwner();
void buildSearchDest();
~QDialog_search();

};

#endif // QDIALOG_SEARCH_H

//.cpp
          QDialog_search::QDialog_search(QWidget *parent):QDialog(parent),
main(new QVBoxLayout()),
tab(new QTabWidget()),
id_l(new QVBoxLayout()),
search_dest(new     QWidget(tab)),search_id(new QWidget(tab))
,search_owner(new QWidget(tab)),ow_l(new QVBoxLayout()),
dest_l(new   QVBoxLayout()){
setLayout(main);
setWindowTitle("SEARCH");
setWindowIcon(QIcon(":/icon/icone/search.png"));
setMinimumSize(200,200);
main->addWidget(tab);
tab->addTab(search_id,"ID");
tab->addTab(search_dest,"destination");
tab->addTab(search_owner,"owner");
buildSearchId();
buildSearchDest();
buildSearchOwner();
}

void QDialog_search::buildSearchId(){
search_id->setLayout(id_l);
QLabel* id_lab=new QLabel("Search ID",search_id);
id_lab->setMaximumSize(60,30);
id_l->addWidget(id_lab);
id_line=new QLineEdit(search_id);id_line->setMaximumSize(120,30);
id_l->addWidget(id_line);
id_button=new QPushButton(search_id);id_button->setMaximumSize(120,30);
id_button->setIcon(QIcon(":/icon/icone/search.png"));
id_l->addWidget(id_button);
}

void QDialog_search::buildSearchOwner(){
search_owner->setLayout(ow_l);
QLabel* ow_lab=new QLabel("Search  owner",search_owner);
ow_lab->setMaximumSize(90,30);
ow_l->addWidget(ow_lab);
ow_line=new QLineEdit(search_owner);ow_line->setMaximumSize(120,30);
ow_l->addWidget(ow_line);
ow_button=new QPushButton(search_owner);ow_button->setMaximumSize(120,30);
ow_button->setIcon(QIcon(":/icon/icone/search.png"));
ow_l->addWidget(ow_button);
}

void QDialog_search::buildSearchDest(){
search_dest->setLayout(dest_l);
QLabel* dest_lab=new QLabel("Search  destination",search_dest);
dest_lab->setMaximumSize(120,30);
dest_l->addWidget(dest_lab);
dest_line=new QLineEdit(search_dest);dest_line->setMaximumSize(120,30);
dest_l->addWidget(dest_line);
dest_button=new QPushButton(search_dest);
dest_button->setMaximumSize(120,30);
dest_button->setIcon(QIcon(":/icon/icone/search.png"));
dest_l->addWidget(dest_button);
}

QDialog_search::~QDialog_search(){
delete main;
delete tab;
delete search_id; // debugger say this is segm fault, search_id is  //QWidget*
delete id_l;
delete id_line;
delete id_button;
delete search_owner;
delete ow_l;
delete ow_line;
delete ow_button;
delete search_dest;
delete dest_l;
delete dest_line;
delete dest_button;
}

我试图删除 "delete search_id" 但调试器证明在 ~QDialog_search() 末尾存在段错误。 有时,当我构建 QDialog_search 时会出现段错误,但只是有时。

该错误源于您和 Qt 处理内存的方式存在分歧。 search_idtab 的子项,因为您将 tab 设置为 search_id(new QWidget(tab)) 中的父项。在 Qt 看来,父对象负责 deleteing 子对象。在析构函数中,你 delete tab; 因此也 delete 是它的子 search_id。然后你 delete search_id,但它不再存在,因此你得到一个分段错误。

我建议您通读 Qt 的 Object Trees & Ownership 以更好地理解所有权模型并避免将来出现此类错误。