我正在用Qt 5.8和Qwt 6.1.3开发一个小型绘图仪应用程序。虽然我认为我正确地理解了Qwt的内存管理方法,但由于我正在使用的QwtPlotItem,例如QwtPlotMarker和QwtPlotCurve,我的应用程序中似乎出现了内存泄漏。我读过这和这以及文档。我遵循给出的规则,但是我仍然有内存泄漏的情节项目。
在我的应用程序中,有一个QwtPlot对象在应用程序运行时一直处于活动状态。在运行时,像QwtPlotMarker和QwtPlotCurve这样的绘图项是attach()、-ed和detach()-ed。我所做的是,我不为任何delete调用QwtPlotItem,而是对Qwt对象使用原始指针。
我不确定一旦QwtPlotITem是detach()-ed,它也会被删除。我在文档中看到了void QwtPlotDict::removeItem(QwtPlotItem* item),我不确定是否应该使用它来删除attach()-ed QwtPlotItem,因为看起来在detach()之后,QwtPlotItems还活着。
我希望任何关于Qwt内存管理的指导。
更新
下面是一个更好的例子。如果没有第二个for循环(我是detach()-ing QwtPlotCurves ),内存使用量是8.2MBS。对于第二个for循环,但是没有delete v[i]; // MANUALLY DELETING QWTPLOTITEM OBJECT,内存使用仍然是8.2MBS。对于第二个for循环和delete v[i]; // MANUALLY DELETING QWTPLOTITEM OBJECT行,内存使用量为5.2MBS。因此,我认为需要手动删除Qwt中的QwtPlotItem。
#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <vector>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QwtPlot* plot = new QwtPlot;
std::vector<QwtPlotCurve*> v;
double x[5] = {0, 1, 2, 3, 4};
double y1[5] = {0, 1.5, 0.3, 2.7, 3.0};
double y2[5] = {0, 0.5, 0.2, 2.0, 1.6};
for(size_t i = 0; i < 2000; i++) {
double y1[5] = {0*i, 1.5*i, 0.3*i, 2.7*i, 3.0*i};
QwtPlotCurve* plotCurve1 = new QwtPlotCurve("CurveXY1");
plotCurve1->setSamples(&x[0], &y1[0], 5);
plotCurve1->attach(plot);
v.push_back(plotCurve1);
}
for(size_t i = 0; i < 1900; i++) {
v[i]->detach();
delete v[i]; // MANUALLY DELETING QWTPLOTITEM OBJECT
}
plot->replot();
plot->show();
return a.exec();
}在上面的例子中,两个if()都有true的条件。因此,plotCurve2没有在detach()之后被删除。
发布于 2017-03-19 12:26:53
我想你误解了论坛上关于指针所有权的帖子。
在qwt中,QwtPlotItems都属于它们被attach()编辑的QwtPlot,所以如果您删除该情节,所有的QwtPlotItems都将被删除。
如果您调用detach(),那么所有权将转移给调用方,因此您需要自己删除它(或者将其删除到另一个地块)。如果它已经为您删除,那么附加到另一个情节将是不可能的。
item.detach(); delete item在内存管理方面非常好,因此删除是必要的。
另一种选择是直接删除它(而不调用.detach())。析构器将为您分离它,然后不存在所有权问题或内存泄漏的风险。
另一种选择是存储std::vector<std::unique_ptr<QwtPlotItem>> (或QList std::set/任何您想要的容器),并在完成之后将它们从向量中擦除。这肯定不会有内存泄漏,但您需要确保向量是在绘图之后创建并在其之前销毁的,否则您将得到双重删除(例如,将向量放在堆栈上,或者在对象内的绘图之后)。
https://stackoverflow.com/questions/42885762
复制相似问题