qDebug()的奇怪行为导致应用程序崩溃

时间:2017-01-10 11:12:26

标签: qt crash qdebug

我一直在调试一个简单的目录应用程序,这个问题开始让我发挥最大的作用。我想创建一个模态对话框,它将收到用户对所呈现数据的输入。我有一个包含目录项数据的简单结构:

struct ItemData {
    int nodeType;
    int nodeID;
    int nodeLevel;
    QString nodeName;
    QString nodeNote;
    QString fileName;
}

然后,在数据输入对话框中表示项目数据的结构

struct DialogData {
    QString name;
    QString note;
    QString file;
}

现在,从主窗口的editRec()方法调用数据输入对话框:

void MainWindow::editRec()
{
    // model is defined in the main window, getSelectedRowData()
    // fills the struct with data properly
    ItemData md = model->getSelectedRowData(ui->treeView->selectionModel());

    // data, on wich the dialog will operate
    DialogData dd;

    dd.name = md.nodeName;
    dd.note = md.nodeNote;
    dd.file = md.fileName;

    // checking whether the data wich is being read from the model
    // and being passed to dialog is correct
    // qDebug '<<' operator is overloaded to handle my structs
//    qDebug << md;        // - outputs data properly, then crashes the program
//    qDebug << dd;        // - also, outputs data properly, then crashes the program

    // suspecting the error in the '<<' overload, I tried to output 
    // one field at a time and it works if I if uncomment one 
    // line at a time, but crashes the application if I try to 
    // output all fields in one go.
//  qDebug() << md.nodeType;
//  qDebug() << md.nodeID;
//  qDebug() << md.nodeLevel;
//  qDebug() << md.nodeName;
//  qDebug() << md.nodeNote;
//  qDebug() << md.fileName;

    DataDialog *dialog;

//  dialog's interface and data handling differs depending on 
//  the type of the node it will operate on
    switch (md.nodeType) {
    case NODE_ROOT: {
        dialog = new DataDialog(dlgEditRoot, false, this);
        dialog->setDialogData(dd, NODE_ROOT);
        break;
    }
    case NODE_BRANCH: {
        dialog = new DataDialog(dlgEditBranch, false, this);
        dialog->setDialogData(dd, NODE_BRANCH);
        break;
    }
    }
    dialog->initWidgets();
    if (dialog->exec() == QDialog::Accepted) {   // showing a modal dialog
        // if user changed the data, modifying the model with the new data
        if (dialog->isDataChanged) {             
            dd = dialog->getDialogData();
            switch (md.nodeType) {
            case NODE_ROOT: {
                md.nodeName = dd.name;
                md.nodeNote = dd.note;
                md.fileName = dd.file;
                model->setSelectedRowData(ui->treeView->selectionModel(), md);
                break;
            }
            case NODE_BRANCH: {
                md.nodeName = dd.name;
                md.nodeNote = dd.note;
                md.fileName = dd.file;
                model->setSelectedRowData(ui->treeView->selectionModel(), md);
                break;
            }
            }
        }
    }
    qDebug() << md;    // - both of these output data correctly without any crashes
    qDebug() << dd;    //
    delete dialog;
}

如果我注释掉前三个qDebug()数据转储,整个过程就会按预期工作。

我发现StackOverflow上只有两个类似的问题:

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

我开始使用Kuba Ober的建议让我对我最初使用的整个数据结构进行了非常深刻的重构,几乎完全重写。虽然我没有找到我之前遇到的崩溃的确切原因,但我能够解决这个问题。

可能会遇到类似问题的人的一些提示。我在初始问题中发布的链接实际上与我的问题直接相关。在第一个链接上,Scott 'scm6079'说:

  

qDebug创建了一个相当重要的缓冲区 - 当它被踩到时   不会让您的计划崩溃

我重写的过程中我得到的确是这种行为:当我的函数没有返回值时,qDebug()是“保存”#39;他们从崩溃。强制所有函数返回值后,崩溃停止。

接下来,如果您没有对QObject实体进行子类化,也不使用智能指针,请特别注意new以使其与适当的delete匹配。不要在condidional分支中创建变量。如果需要根据condidtion创建对象,请将构造函数中的不同位重构为方法,您将在创建后从条件分支调用。虽然我不确定它是否具有良好的编码风格,但它确实帮助我修复了崩溃。