【问题标题】:Cannot figure out double free or corruption (fasttop) error无法找出双重释放或损坏(fasttop)错误
【发布时间】:2017-03-07 14:11:30
【问题描述】:

以下方法在运行时生成双重释放或损坏 (fasttop) 错误(在第一行)。它是随机发生的,即它可能发生在程序运行的第一秒或 35 秒。

QSharedPointer<QPixmap> Utils::loadImg(QString fileName)
{
    QPixmap *pixmap = new QPixmap(fileName);
    QSharedPointer<QPixmap> qspPixmap(pixmap);
    return qspPixmap;
}

这是一个静态方法,我调用它来获取像素图的指针(实际上是使用 Qt 提供的智能指针)。获得智能指针后,我将其存储到地图结构中以备后用。当我从地图结构中删除条目时,它应该释放内存,并且看起来确实如此。 请注意,loadImg(QString) 方法是由另一个在其自己的线程上运行的方法调用的(使用 Qt 提供的 QtConcurrent 和 QFuture)。

我真的无法弄清楚问题是什么。调试器将第一行显示为有问题的行。

提前感谢您的帮助。

【问题讨论】:

  • 哪一行是“第一”行?如果您使用的是 Linux,请尝试使用 valgrind。
  • 在你到达那条线之前很可能发生了一些不好的事情,但那是内存管理器发现损坏的时候。您需要向后工作并检查到目前为止的所有内存管理。
  • 在 valgrind 下运行您的应用程序可能会帮助您找到堆最初损坏的位置。
  • 大家好,第一行是指创建原始指针(不是智能指针)的行。我在 Linux 上,所以我会按照你的建议尝试 valgrind,我根本没有使用它的经验。

标签: c++ qt


【解决方案1】:

鉴于像素图是隐式共享的,这种方法毫无意义。按价值传递它们!您还应该通过 const 引用传递字符串参数,除非您打算在方法内部修改它们。

您完全可以拥有QMap&lt;QString, QPixmap&gt; 并将一切都视为价值。

如果有任何机会,您在除主线程之外的任何线程中调用此方法,您将调用未定义的行为 - 您应该改用 QImage

您的方法应如下所示:

QPixmap Utils::loadImg(const QString & fileName)
{
   Q_ASSERT(QThread::currentThread() == qApp->thread());
   return QPixmap{fileName};
}

如果您打算在任意线程中调用它,您应该:

QImage Utils::loadImg(const QString & fileName)
{
   return QImage{fileName};
}

当然,无论哪种情况,该方法都是微不足道的,因此除了验证您是否在正确的线程中创建像素图之外,无需使用它。

【讨论】:

  • 感谢您的帮助。你的回答解决了我的问题。我理解为什么我不应该使用 QSharedPointer,因为正如您所说,QPixmap 和 QImage 是隐式共享的。但是,我不明白为什么在从主线程调用该方法时可以/应该返回 QPixmap,而在不从主线程调用它时必须返回 QImage。你能解释一下吗?谢谢。
  • QPixmap 不能在主线程之外使用。就这样。您根本不必使用QPixmap:默认图形后端是光栅后端,所有像素图在内部都是QImages,具有屏幕兼容格式。因此,您不妨先使用QImageQPixmap 在光栅后端没有任何速度优势任何形式。没有。您只需要使用它来与本机代码进行互操作 - 即使这样也有可能。
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多