Deleting pointer to QwtPlot segmentation fault
Hello, I have become the new maintainer of an old Qt/QWT project.
I am almost done porting it to Qt 5 from Qt 4 and from Qwt 4 to Qwt 6.
However, i'm getting a segmentation fault when deleting the pointer to a QwtPlot.
The code is very old and i have yet to clean it up as it is quite large and right now i'm just trying to get it to work.
Constructor for the class "axes"
Code:
title_ = title;
tabwidget_ = tabwidget;
menu_ = menu;
//QScopedPointer<QwtPlot> axes_(new QwtPlot(title_));
axes_
= new QwtPlot(title_
);
// This is the pointer i cannot delete
graphdialog_ = new GraphDialog(title_);
xpicker_
= new QwtPicker(static_cast<QWidget
*>
(axes_
->axisWidget
(2)));
ypicker_
= new QwtPicker(static_cast<QWidget
*>
(axes_
->axisWidget
(0)));
windowaction_
= new QAction(title_,
this);
autoscaleaction_
= new QAction("Autoscale",
this);
gridaction_
= new QAction("Show grid",
this);
xaxislimitsaction_
= new QAction("Set x scale",
this);
yaxislimitsaction_
= new QAction("Set y scale",
this);
grid_->hide();
grid_->show();
tabwidget_->addTab(axes_, title_);
menu_->insertAction(0,autoscaleaction_);
menu_->insertAction(0,gridaction_);
graphdialog_->menu()->insertAction(0,autoscaleaction_);
graphdialog_->menu()->insertAction(0,gridaction_);
xpicker_->setStateMachine(pickermachine_);
xpicker_
->setTrackerMode
(QwtPicker::ActiveOnly);
ypicker_->setStateMachine(pickermachine_);
ypicker_
->setTrackerMode
(QwtPicker::ActiveOnly);
canvaspicker_->setStateMachine(pickermachine_);
canvaspicker_
->setTrackerMode
(QwtPicker::ActiveOnly);
graphsNum_ = 0;
QFont font
= axes_
->axisFont
(0);
font.setPointSize(8);
axes_->setAxisFont(0,font);
axes_->setAxisFont(1,font);
axes_->setAxisFont(2,font);
axes_->setAxisFont(3,font);
axes_->legend()->setFont(font);
font = axes_->titleLabel()->font();
font.setPointSize(12);
axes_->titleLabel()->setFont(font);
axes_->setAutoFillBackground(true);
axes_->setAutoDelete(false);
grid_
->setMajorPen
(QColor(Qt
::black),
0.5,Qt
::DashLine);
grid_->attach(axes_);
autoscaleaction_->setCheckable(true);
autoscaleaction_->setChecked(false);
gridaction_->setCheckable(true);
gridaction_->setChecked(true);
windowaction_->setCheckable(true);
windowaction_->setChecked(true);
connect(xpicker_,
SIGNAL(selected
(const QPolygon &)),
this,
SLOT(xAxisClicked
(QPolygon)));
connect(ypicker_,
SIGNAL(selected
(const QPolygon &)),
this,
SLOT(yAxisClicked
(QPolygon)));
connect(canvaspicker_,
SIGNAL(selected
(const QPolygon &)),
this,
SLOT(canvasClicked
(QPolygon)));
connect(windowaction_, SIGNAL(toggled(bool)), this, SLOT(setDocked(bool)));
connect(autoscaleaction_, SIGNAL(toggled(bool)), this, SLOT(setAutoscale(bool)));
connect(gridaction_, SIGNAL(toggled(bool)), this, SLOT(showGrid(bool)));
connect(xaxislimitsaction_, SIGNAL(triggered()), this, SLOT(xAxisClicked()));
connect(yaxislimitsaction_, SIGNAL(triggered()), this, SLOT(yAxisClicked()));
axes_
->axisWidget
(QwtPlot::xBottom)->setMinBorderDist
(0,
20);
axes_->plotLayout()->setAlignCanvasToScales(true);
xhistory_ = 30;
xmax_ = 0;
ymin_ = 1e10;
ymax_ = -1e10;
axes_->setContextMenuPolicy(Qt::CustomContextMenu);
connect(axes_,
SIGNAL(customContextMenuRequested
(QPoint)),
this,
SLOT(customContextMenuRequested
(QPoint)));
}
The destructor:
Code:
Axes::~Axes(){
#ifdef SHOW_DESTRUCTORS
qDebug() << "Destroying " << axes_->title().text();
#endif
foreach(Graph* graph, graphs_)
delete graph;
graphs_.clear();
barplots_.clear();
graphsNum_ = 0;
delete graphdialog_;
delete windowaction_;
delete autoscaleaction_;
delete gridaction_;
delete axes_; // this line causes the segmentation fault
#ifdef SHOW_DESTRUCTORS
qDebug() << "Destroyed!!";
#endif
}
Basically every forum I have read with "deleting pointer causes segmentation fault" is because it hasn't been assigned with "new" - but it is in my case.
I also tried using a smart pointer but couldn't get it to work.
I hope you can help me
Edit: I forgot to mention, we have an old compiled version of the project, where this works - so something, either in Qt or Qwt has changed so it doesn't work anymore.
Best Regards
David
Re: Deleting pointer to QwtPlot segmentation fault
I found a solutions, though I'm not entirely sure I understand why.
But editing the deconstructor from :
Code:
Axes::~Axes(){
#ifdef SHOW_DESTRUCTORS
qDebug() << "Destroying " << axes_->title().text();
#endif
foreach(Graph* graph, graphs_)
delete graph;
graphs_.clear();
barplots_.clear();
graphsNum_ = 0;
delete graphdialog_;
delete windowaction_;
delete autoscaleaction_;
delete gridaction_;
delete axes_; // this line causes the segmentation fault
#ifdef SHOW_DESTRUCTORS
qDebug() << "Destroyed!!";
#endif
}
to
Code:
Axes::~Axes(){
#ifdef SHOW_DESTRUCTORS
qDebug() << "Destroying " << axes_->title().text();
#endif
tabwidget_->clear();
#ifdef SHOW_DESTRUCTORS
qDebug() << "Destroyed!!";
#endif
}
seems to fix it and it works now.
My guess is that tabwidget was the parent of everything and telling it to clear all works.
I guess since the old times a lot more has been done to help automatically clear up any data on the heap/stack, such as pointers.
I hope this can help someone else too.
Best regards
David
Re: Deleting pointer to QwtPlot segmentation fault
You can verify using valgrind if indeed nothing is "leaking", e.g. if indeed you don't have to free anything extra.
Re: Deleting pointer to QwtPlot segmentation fault
Hi, you probably get the segfault because you don't own "axes_" anymore. The QTabWidget takes ownership when you call addTab(), and will take care of destruction.
Ginsengelf
Re: Deleting pointer to QwtPlot segmentation fault
Quote:
Originally Posted by
flok
You can verify using valgrind if indeed nothing is "leaking", e.g. if indeed you don't have to free anything extra.
Thank you, I will try out Valgrind
Best regards
David
Re: Deleting pointer to QwtPlot segmentation fault
I don't know if any of you care.
But the project is finally succesfully ported to Qt5.10 and Qwt6.1.3
I now have both a compiled Windows and Linux version
It's been though, but I got through!
Thanks to everyone who has help me out underway.
Best regards
David