笔者在做一个长期监测系统的上位机的时候,使用Qcustomplot绘制多个图表,在实际运用过程中出现了几个小时闪退的问题,闪退的时候没有任何报错。
而后在QT的debug模式下,使用虚拟串口自动发送指令进行测试,几个小时候后上位机闪退,窗口报错如下:
terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
经过网上查找后发现可能是内存超出的问题,在任务管理器中也可以发现,上位机在实际工作中的内存不断变大,由此断定应该是程序里面某部分内存没有得到释放。一开始怀疑是串口buf的问题,检查后发现该内存得到释放。之后想到在绘制的图表中,可以拖动看到历史数据曲线,这一部分内存是在不断累计,没有得到释放。
在学习了这篇博客后解决了问题,根据自己闪退的时间,保守选择Qcustomplot历史数据保留的时间。经过实际验证,使用任务管理器进行观察,内存在达到清除时间后便不再增大。【Qt】解决QCustomPlot实时绘图时数据不断累积的问题_qt qcustomplot 缓存数据_漫游宇宙sky的博客-CSDN博客
1. 修改qcustomplot.h文件
在void addData(double key, double value);
下面增加void removeDataBefore(int x);
的成员函数声明。
// non-property methods:
void addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
void addData(double key, double value);
void removeDataBefore(int x);
2.修改qcustomplot.cpp文件
在QCPGraph::addData
下面增加void removeDataBefore(int x);
的成员函数定义。
void QCPGraph::removeDataBefore(int x)
{
mDataContainer->removeBefore(x); // 此处直接将x传入,而非mDataContainer->size()-size
}
3.调用removeDataBefore方法
一般实时绘图以时间戳为x坐标,则调用方法如下,表示删除前25秒的数据。
double xTime = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
ui->GyroPlot->graph(0)->addData(xTime, gyro[0]);
ui->GyroPlot->graph(0)->removeDataBefore(xTime - 25);