类构造函数中指向QProcess对象的指针导致qt GUI崩溃

pointer to QProcess object in class constructor crashes qt GUI

本文关键字:指针 qt 崩溃 GUI 对象 构造函数 QProcess      更新时间:2023-10-16

我有一个qt GUI应用程序,它包含一个从QFrame派生的小部件DS9,用于打开和操作外部程序。该类的实现如下所示:

ds9.h

#ifndef DS9_H
#define DS9_H
#include <QFrame>
#include <QProcess>
class DS9 : public QFrame
{
    Q_OBJECT
public:
    explicit DS9(QWidget *parent = 0);
    ~DS9();  
signals:

public slots:
    void runDS9();
private:
    QProcess *ds9;
};
#endif // DS9_H

ds9.cpp

DS9::DS9(QWidget *parent):
    QFrame(parent)
{
    ds9 = new QProcess();
    ds9->setProgram("ds9");
    QStringList arguments;
    arguments << "-invert" << "-zscale";
    ds9->setArguments(arguments);
}
DS9::~DS9()
{
    delete ds9;
}
void DS9::runDS9()
{
    ds9->start();
}

然而,当运行程序时,不是显示GUI,而是出现一个黑色(不是空白)窗口并立即崩溃。错误信息如下所示:

*** Error in `./lightcurve_examiner': double free or corruption (out):        0x00000000013f0610 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x77a8d)[0x7f0a9dcada8d]
/lib64/libc.so.6(cfree+0x5cd)[0x7f0a9dcb9d2d]
/lib64  /libQt5Core.so.5(_ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11Q    ThreadData+0x2d0)[0x7f0a9efd0a20]
/lib64/libQt5Core.so.5(+0x2d9983)[0x7f0a9f024983]
/lib64/libglib-2.0.so.0(g_main_context_dispatch+0x15a)[0x7f0a9d2eca8a]
/lib64/libglib-2.0.so.0(+0x49e20)[0x7f0a9d2ece20]
/lib64/libglib-2.0.so.0(g_main_context_iteration+0x2c)[0x7f0a9d2ececc]
.....

但是,如果我不将QProcess *ds9设置为类的成员,即,执行如下操作:

. h

:

...
    private:
      //  QProcess *ds9;
...
. cpp

:

void DS9::runDS9()
{
    QProcess * ds9 = new QProcess();
    ds9->setProgram("ds9");
    QStringList arguments;
    arguments << "-invert" << "-zscale";
    ds9->setArguments(arguments);
    ds9->start();
}

一切正常,也就是说,GUI正常启动,通过调用插槽,程序被正确调用。

我的问题是,为什么我不能把QProcess对象作为类的成员?如果确实如此,我如何保留指针并访问/重用它?

谢谢!

对我来说,似乎DS9对象的生命周期可能存在问题,即它被删除得太快,因此代码的问题是类的外部问题。前几天我遇到了同样的问题,这个问题与我的混乱测试代码有关,该代码创建了一个在调用QApplication::exec()之前被删除的QProcess。如果您还没有尝试过,我建议您从QProcess派生一个类,并向它的析构函数和DS9的析构函数添加一个日志调用,或者查看是否可以在这些析构函数中添加断点,并从外部查看程序流。另外,您可能希望更改对QProcess的构造函数调用,以将DS9对象添加为父对象,这将使您不必在DS9的析构函数中手动调用delete。

祝你好运