c++ - QSerialBus 工作中的内存泄漏

标签 c++ qt memory-leaks

大家好!

我在 Qt 5.8 上通过 QSerialBus 库实现 ModBus 时遇到问题。

问题是 - 当我尝试高速读取离散输入列表时,程序发现内存泄漏 - 大约每秒 300-350Kb

所以,这里是导致泄漏的函数代码:

void ModBus::queue()
{
    if(!_readList.isEmpty())
    {
        if(!checkState())
        {
            _readList.clear();
            _curPos = DiscInputPos::Full;
            queue();
            return;
        }

        QModbusDataUnit readData = QModbusDataUnit(QModbusDataUnit::DiscreteInputs, _readList.first(), 1);
        if(auto *reply = _client->sendReadRequest(readData, _serverNum))
        {
            if(!reply->isFinished())
            {
                connect(reply, &QModbusReply::errorOccurred, [=] (QModbusDevice::Error e)
                {
                    reply->deleteLater();
                    if(e == QModbusDevice::TimeoutError)
                    {
                        _readList.clear();
                        _curPos = DiscInputPos::Full;
                        stop();
                        start();
                        queue();
                    }
                });
                connect(reply, &QModbusReply::finished, this, [=]
                {
                    if(reply->error() == QModbusDevice::NoError)
                    {
                        if(reply->result().valueCount() > 0)
                        {
                            _curPos = (DiscInputPos) reply->result().value(0);
                            if(_curPos == DiscInputPos::Clear)
                                _readList.removeFirst();
                            else
                                _readList.clear();
                        }
                    }
                    else
                    {
                        _readList.clear();
                        _curPos = DiscInputPos::Full;
                    }

                    reply->deleteLater();
                    queue();
                });
            }
            else
                delete reply;
        }
        else
        {
            delete reply;
            _readList.clear();
            _curPos = DiscInputPos::Full;
            queue();
        }
    }
    else
    {
        emit sendReadResult(_curPos);
        _curPos = DiscInputPos::Full;
    }
}

_clientQModbusTcpClient

bool checkState() — 除非检查连接状态,否则什么都不做。

最大 _readList 大小为 4

如果我用 _client->sendReadRequest 注释部分代码 - 一切正常,没有任何泄漏。任何人都可以解释 - 它可以是什么?

提前致谢!

最佳答案

我通过计时器在 0.5 秒 上解决了这个问题(较少也会导致泄漏),它作为检查来自 ModBus 类答案的类的单次滴答滴答作响。仍然有泄漏,但少得多。如果 1 秒 - 没有泄漏。

connect(d, &ModBus::sendReadResult, this, &StatusesWorker::getRead);

void StatusesWorker::getRead(DiscInputPos s)
{
        bool cleared = (s == DiscInputPos::Clear);

        if(!cleared)
            emit badSensors();
        else
            emit clearSensors();

        QTimer::singleShot(500, [=] { checkSensor(id); });
    }
}

但我认为这是一个糟糕的解决方案。

UPD。

Qt 社区 solved这样的问题:

connect(reply, &QModbusReply::destroyed, [this] { QTimer::singleShot(60, [this] { queue(); }); });

而且它的工作速度更快,没有泄漏。当然,checkSensor() 现在可以在没有计时器的情况下运行。

关于c++ - QSerialBus 工作中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42804640/

相关文章:

c++ - std::optional has_value() 怎么可能是 constexpr?

c++ - QML 和 C++ 属性 - ReferenceError : Can't find variable

javascript - 是否有必要在递归调用的计时器中清除超时?

c++ - ==<> 运算符的含义是什么?

c++ - 使用 SCons 提取每个编译单元的编译时间

c++ - 这个元素在 c++ Qt 中被称为什么?

c++ - Qt - 首选使用什么 - 小部件或 View ? (树、表、列表)

c++ - [Qt][Linux] 列出驱动器或分区

memory-leaks - MPI 内存泄漏

c++ - 这会产生内存泄漏吗?