我正在使用Qt 5.8
和Qwt 6.1.3
开发一个小型绘图仪应用程序。虽然我认为我正确理解了Qwt的内存管理方法,但由于QwtPlotItem
我正在使用,我的应用程序中似乎有内存泄漏;例如QwtPlotMarker
和QwtPlotCurve
。我已阅读this和this以及文档。我遵循那里给出的规则,但是我仍然有内存泄漏的情节项目。
在我的应用程序中,有一个QwtPlot
对象在应用程序运行时始终处于活动状态。在运行时期间,QwtPlotMarker
和QwtPlotCurve
等绘图项目为attach()
- ed和detach()
。我所做的是,我没有为任何delete
调用QwtPlotItem
,我使用原始指针来表示Qwt对象。
我不确定QwtPlotITem
detach()
是否一旦被删除。我在文档中看到了void QwtPlotDict::removeItem(QwtPlotItem* item)
,我不确定是否应该使用它来删除attach()
- ed QwtPlotItem
,因为它似乎是在{{1 },detach()
s仍在堆上。
我很感激有关Qwt内存管理的任何指导。
更新:
下面是一个更好的例子。如果没有第二个for循环,我QwtPlotItem
- detach()
s,内存使用量为8.2 Mbs。使用第二个for循环但没有QwtPlotCurve
,内存使用量仍为8.2 Mbs。使用第二个for循环和delete v[i]; // MANUALLY DELETING QWTPLOTITEM OBJECT
行,内存使用量为5.2 Mbs。所以我认为需要在Qwt中手动删除delete v[i]; // MANUALLY DELETING QWTPLOTITEM OBJECT
。
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
未被删除。
答案 0 :(得分:3)
我认为你误解了关于指针所有权的论坛帖子。
在qwt中,QwtPlotItems全部归QwtPlot所有,它们被attach()
编辑,所以如果删除该图,所有QwtPlotItem都将被删除。
如果您致电detach()
,则所有权将转移给来电者,因此您需要自行删除(或.attach()
将其删除到其他地块)。如果它被删除了,则无法附加到另一个地块。
item.detach(); delete item
关于内存管理非常好,删除 是必要的。
另一种方法是直接删除它(不调用.detach()
)。析构函数将为您分离它,然后没有所有权问题或内存泄漏的风险。
另一个替代方法是存储std::vector<std::unique_ptr<QwtPlotItem>>
(或QList std :: set /你想要的任何容器),并在完成时将其从向量中删除。这肯定不会有内存泄漏,但是你需要确保在绘图之后创建向量并在它之前销毁,否则你将获得双删除(例如,将向量放在堆栈上,或者在对象内部绘图之后)