Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt program crash when I delete qwtplot array.



  • OS: Ubuntu 18.02
    GCC version 7.4.0
    QMake Version 3.1
    Qt Version 5.9.5
    QWT Version 6.1.4

    Hello Everyone

    I created a qwtplot array, and set a point on origin at them.

    When I delete the qwtplot array before close windows, the Qt is crashed.

    The Code is show in the following

    mainwindows.h

    #include <QMainWindow>
    #include <qwt_plot.h>
    #include <qwt_plot_curve.h>
    #include <qwt_plot_grid.h>
    #include <qwt_plot_canvas.h>
    #include <qwt_plot_curve.h>
    #include <qwt_plot_grid.h>
    #include <qwt_symbol.h>
    #include <QPolygonF>
    namespace Ui {
    class MainWindow;
    }
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    private:
        Ui::MainWindow *ui;
        QwtPlot *qwtpt;
        QPolygonF *polygon;
        QwtPlotCurve *curve;
        QwtPlotGrid *grid;
        QwtSymbol *symbol;
    };
    

    mainwindow.cpp

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        int numpoints = 10;
        qwtpt = new QwtPlot[numpoints];
        polygon = new QPolygonF[numpoints];
        curve = new QwtPlotCurve[numpoints];
        grid = new QwtPlotGrid[numpoints];
        symbol = new QwtSymbol[numpoints];
        QString style = "color: white; ";
        QPolygonF initialpoint;
        initialpoint << QPointF(0.0f, 0.0f);
        int k;
        for(k = 0; k < numpoints; ++k){
            //plot
            qwtpt[k].setParent(ui->scrollArea);
            qwtpt[k].setGeometry(10, 20 + 181 * k, 760, 161);
            qwtpt[k].setAxisTitle(QwtPlot::xBottom, "points");
            qwtpt[k].setAxisTitle(QwtPlot::yLeft, "efficience %");
            qwtpt[k].setAxisScale(QwtPlot::xBottom, 0.0, 132);
            qwtpt[k].setAxisScale(QwtPlot::yLeft, 0.0, 100);
            qwtpt[k].setStyleSheet(style);
            //symbol
            symbol[k].setPen(QPen(Qt::red, 2));
            symbol[k].setStyle(QwtSymbol::Ellipse);
            symbol[k].setBrush(QBrush(Qt::yellow));
            symbol[k].setSize(QSize(8,8));
            //curve
            curve[k].setPen(Qt::blue, 4);
            curve[k].setRenderHint(QwtPlotItem::RenderAntialiased, true);
            curve[k].setSymbol(&symbol[k]);
            curve[k].attach(&qwtpt[k]);
            curve[k].setSamples(initialpoint);
            //grid
            grid[k].attach(&qwtpt[k]);
        }
    }
    MainWindow::~MainWindow()
    {
        delete [] qwtpt;	//  crash on this line
        delete [] polygon;
        delete [] curve;
        delete [] grid;
        delete [] symbol;
        delete ui;
    }
    

    if I do not to delete the qwtpt array, the Qt debug show the crash on function ~MainWindow()

    if I exchange between qwtpt and curve, the crash is happened on “delete [] curve”

         delete [] curve;	//  crash on this line
        delete [] polygon;
        delete [] qwtpt;
        delete [] grid;
        delete [] symbol;
        delete ui;
    

    Is anyone have idea, or some suggestion for this issues?

    Thanks in advance.


  • Lifetime Qt Champion

    Hi,

    You are deleting objects that are properly parented and/or owned. Therefore you are triggering a double delete hence your crash.



  • I change method to create the qwtplot object

    from

    QwtPlot *qwtpt = new QwtPlot[numpoints];
    

    to

    QVector<QwtPlot *> qwtplot;
    qwtplot.resize(numpoints );
    for(int k = 0; k < numpoints ; ++k)
        qwtplot = new QwtPlot (this);
    

    So I don't need to delete qwtplot array;
    The Program is worked fine;

    But
    The QwtPlotCurve object is crashed when I set setSymbol before delete it;
    Maybe this is a bug.


  • Lifetime Qt Champion

    @LeonSu said in Qt program crash when I delete qwtplot array.:

    So I don't need to delete qwtplot array;

    Using a static c array or a QVector does not change anything if the object must be deleted manually or not.

    The QwtPlotCurve object is crashed when I set setSymbol before delete it;

    A bug on your side I would guess - please show us your current code.



  • Thank you for your reply. Christian Ehrlicher

    The test code as following

    mainwindow.h

    #include <QMainWindow>
    
    #include <qwt_plot.h>
    #include <qwt_plot_curve.h>
    #include <qwt_plot_grid.h>
    #include <qwt_plot_canvas.h>
    #include <qwt_plot_curve.h>
    #include <qwt_plot_grid.h>
    #include <qwt_symbol.h>
    #include <QPolygonF>
    #include <QVector>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
        const int numpoints = 10;
    
        QVector<QwtPlot *> qwtpt;
        QPolygonF *polygon;
        QwtPlotCurve *curve;
        QwtPlotGrid *grid;
        QwtSymbol *symbol;
    };
    

    mainwindow.cpp

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        polygon = new QPolygonF[numpoints];
        curve = new QwtPlotCurve[numpoints];
        grid = new QwtPlotGrid[numpoints];
        symbol = new QwtSymbol[numpoints];
    
        QString style = "color: white; ";
    
        int k;
        for(k = 0; k < numpoints; ++k)
            polygon[k] << QPointF(0.0f, 0.0f);
    
        qwtpt.resize(numpoints);
    
        for(k = 0; k < numpoints; ++k){
            //plot
            qwtpt[k] = new QwtPlot(ui->scrollArea);
            qwtpt[k]->setGeometry(10, 20 + 181 * k, 760, 161);
            qwtpt[k]->setAxisTitle(QwtPlot::xBottom, "points");
            qwtpt[k]->setAxisTitle(QwtPlot::yLeft, "efficience %");
            qwtpt[k]->setAxisScale(QwtPlot::xBottom, 0.0, 132);
            qwtpt[k]->setAxisScale(QwtPlot::yLeft, 0.0, 100);
            qwtpt[k]->setStyleSheet(style);
    
            //symbol
            symbol[k].setPen(QPen(Qt::red, 2));
            symbol[k].setStyle(QwtSymbol::Ellipse);
            symbol[k].setBrush(QBrush(Qt::yellow));
            symbol[k].setSize(QSize(8,8));
    
            //curve
            curve[k].setPen(Qt::blue, 4);
            curve[k].setRenderHint(QwtPlotItem::RenderAntialiased, true);
            curve[k].attach(qwtpt[k]);
            curve[k].setSamples(polygon[k]);
            curve[k].setSymbol(&symbol[k]);
    
            //grid
            grid[k].attach(qwtpt[k]);
        }
    }
    
    MainWindow::~MainWindow()
    {
    
        delete [] symbol;
        delete [] polygon;
        delete [] grid;
        delete [] curve; //crash on this line
        delete ui;
    }
    

    if I marked "curve[k].setSymbol(&symbol[k]); " in MainWindow, the program will work fine.

    //curve[k].setSymbol(&symbol[k]);
    

  • Lifetime Qt Champion

    Even if I can't find it directly in the documentation (you may ask the qwt maintainer for this), QwtPlot takes ownership of all QwtPlotItems which are attached via attach(). Therefore you're working on a dangling pointer.


Log in to reply