2015-09-02 2 views
4

У меня есть приложение GUI GUI, которое содержит виджет DS9, полученный из QFrame, для открытия и работы с внешней программой. Реализация класса выглядит следующим образом:указатель на объект QProcess в конструкторе crash qt GUI

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(); 
} 

все прекрасно работает, то есть графический интерфейс начинает работать нормально, и называют g слот, программа будет правильно вызвана.

Мой вопрос: почему я не могу поместить объект QProcess в качестве члена класса? Если это действительно так, как я могу сохранить указатель и получить доступ/повторно использовать его?

Спасибо!

+4

Единственное различие, которое я вижу, это то, что один раз вы удаляете и один раз, когда вы не удаляете объект процесса. Возможно, перед удалением должен быть установлен 'ds9-> waitForFinished()', потому что delete завершает процесс, и вы можете подождать, пока он не завершится добровольно. Можете ли вы создать простой пример приложения, я могу запустить себя, чтобы проверить ошибки. –

+0

Попробуйте получить лучшую обратную трассировку с полной информацией об отладке. –

+1

Удалите папку сборки, снова создайте проект и посмотрите, работает ли он. Если это все равно, то вы создаете экземпляр 'DS9', прежде чем' QApplication' будет построен, возможно? –

ответ

1

Для меня, похоже, может возникнуть проблема с временем жизни вашего объекта DS9, то есть он удаляется слишком рано, и поэтому проблема с вашим кодом является внешней по отношению к вашему классу. У меня была та же самая проблема на днях, и проблема заключалась в том, чтобы связать мой тестовый код, который создал QProcess, который был удален до вызова QApplication :: exec(). Я бы порекомендовал, если вы еще не пробовали это, чтобы получить класс из QProcess и добавить вызов регистрации его деструктору и деструктору DS9 или посмотреть, можете ли вы добавить точки останова в этих деструкторах и посмотреть поток вашей программы извне. Кроме того, в качестве дополнительной точки вам может потребоваться изменить вызов конструктора на QProcess, чтобы добавить объект DS9 в качестве родителя, что избавит вас от необходимости вручную удалять вызов в деструкторе DS9.

Удачи :)

Смежные вопросы