【问题标题】:QProcess causes memory leakQProcess 导致内存泄漏
【发布时间】:2014-08-28 04:13:34
【问题描述】:

我正在构建一个 C++/Qt5.1 应用程序,它使用 QProcess 启动另一个程序,然后等待结果。每次我运行这段代码时,valgrind 都会在第 2 行(起始行)说内存丢失。

QProcess command(this);
command.start(commandpath, myParameters);
if (command.waitForStarted(waitToStart)) {
    command.write(myStdIn.toLatin1());
    command.closeWriteChannel();
    if (command.waitForFinished(waitToFinish)) {
        myStdOut = command.readAllStandardOutput();
        myStdErr = command.readAllStandardError();
    }
}
command.deleteLater();

我添加了 deletelater() 行,但没有帮助。 (请注意,仅当“commandpath”程序未成功运行时才会发生内存丢失 - 例如,当我尝试运行不存在的程序时)。

谁能解释一下为什么,以及如何解决这种记忆丧失?

如果有帮助,这里有一些 valgrind 输出:

16 bytes in 1 blocks are definitely lost in loss record 57 of 678
  in RunProcessWorker::run(RunProcessWorker::EMutex, QString, QString, QString, bool, QString, QStringList, QStringList, QString, QString&, QString&, unsigned int, unsigned int, unsigned long long&, RunProcessWorker::EResultCodes&, QProcess::ProcessError&, int&) in /mnt/lserver2/data/development/haast/src/systemcommands/runprocessworker.cpp:249
  1: operator new[](unsigned long) in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
  2: /opt/Qt5.1.0/5.1.0/gcc_64/lib/libQt5Core.so.5.1.0
  3: QProcess::open(QFlags<QIODevice::OpenModeFlag>) in /opt/Qt5.1.0/5.1.0/gcc_64/lib/libQt5Core.so.5.1.0
  4: QProcess::start(QString const&, QStringList const&, QFlags<QIODevice::OpenModeFlag>) in /opt/Qt5.1.0/5.1.0/gcc_64/lib/libQt5Core.so.5.1.0
  5: RunProcessWorker::run(RunProcessWorker::EMutex, QString, QString, QString, bool, QString, QStringList, QStringList, QString, QString&amp;, QString&amp;, unsigned int, unsigned int, unsigned long long&amp;, RunProcessWorker::EResultCodes&amp;, QProcess::ProcessError&amp;, int&amp;) in <a href="file:///mnt/lserver2/data/development/haast/bin/debug/../../src/systemcommands/runprocessworker.cpp:249" >/mnt/lserver2/data/development/haast/src/systemcommands/runprocessworker.cpp:249</a>

【问题讨论】:

  • 而且即使QProcess对象超出范围并被破坏内存也没有释放?
  • 否 - 在方法(包含上述代码)超出范围后,valgrind 抱怨。 (这是在一个单独的线程中运行 - 所以我在程序仍在运行时看到了错误)
  • 请注意,您的command 没有分配新的,因此使用它执行delete 会崩溃(幸运的是,这里的对象超出范围并在deleteLater 生效之前销毁)。跨度>
  • 我缺乏 Qt 专业知识,无法确定,这个错误可能与此有关吗? (bugreports.qt-project.org/browse/QTBUG-33021) 注意程序不执行时内存丢失的情况!
  • 我升级到 Qt Creator 5.3.1(其中应该包含对这个错误的修复),但错误仍然存​​在。 (我假设 qt-creator 捆绑了最新的 Qt 库)

标签: c++ qt memory-leaks qprocess


【解决方案1】:

并非所有valgrind 的发现都是“真正的”内存泄漏,或者您应该关心的泄漏。只要内存“泄漏”来自库,并且即使您多次执行失败的事情也不会增长,那么就不用担心。

尽管在应用程序中这被认为是不好的做法,但库可能会从堆中分配东西,而这些东西永远不会被释放。库可以添加一个退出处理程序来释放它们,但它会减慢程序的退出速度而没有真正的收益,因为操作系统无论如何都会以一大块释放资源。

出于这个原因,valgrind 支持suppressing errors。使用 Qt 最简单的方法是 run valgrind under Qt Creator,默认情况下它有一个正确的 Qt 库抑制文件。


如果您担心这实际上是一个 Qt 错误,那么您应该编写代码,在循环中执行一百万次泄漏操作。如果泄漏的大小增加,那就不好了,您可能应该file a bug report 使用代码来重现它。即使它是不常见代码路径中的一次性泄漏,修复它也可能是好的,而不是留下无用的分配来混乱堆。

【讨论】:

  • 我对 Qt 太陌生了——我不想创建错误报告,直到我确定这不是我正在做的愚蠢的事情。我确实直接从 Qt Creator 运行 valgrind...所以我认为它只是向我展示了真正的内存泄漏?!
  • 好吧,如果 valgrind 甚至在 Qt Creator 下也抱怨,那么 要么 它应该在 Qt 库中修复, 或者 抑制文件 Qt应更新创建者使用以忽略它。因此,如果您可以编写一个简短的代码来重现这一点,我会提交一份错误报告,其中包含代码和重现说明(可能先询问at irc)。
  • 我连续运行了 10 次,内存泄漏只在第一次调用 start() 时出现。这是否意味着这是“好的”? (有点泄漏好吗?还是我误解了这意味着什么)
  • 嗯,首先它听起来像 库问题,但它不会导致您的应用程序出现任何问题,因此您无需担心。从 Qt 的角度来看,应该对其进行调查,并且应该修复 something,如上一条评论中所述。
猜你喜欢
  • 1970-01-01
  • 2015-07-06
  • 2014-06-07
  • 2013-11-20
  • 2011-10-28
  • 2016-01-18
  • 2012-12-13
  • 1970-01-01
  • 2011-01-08
相关资源
最近更新 更多