【问题标题】:Qlist<QCameraInfo> causes access violation in QList destructorQlist<QCameraInfo> 导致 QList 析构函数中的访问冲突
【发布时间】:2016-06-02 23:56:02
【问题描述】:

我正在使用 Qt5 用 C++ 编写视频抓取应用程序。我正在关注他们的示例代码并查看获取相机信息的文档: http://doc.qt.io/qt-5/qcamerainfo.html

我遇到的问题是,在我使用规定的技术获取相机数据后(效果很好):

QList<QCameraInfo>cameraInfos = QCameraInfo::availableCameras();

每当cameraInfos 超出范围时,我都会收到Access violation 错误。

例如,如果我这样做:

void readDeviceInfo(void) {

    // Camera devices:
    QList<QCameraInfo>cameraInfos = QCameraInfo::availableCameras()
    for (QList<QCameraInfo>::Iterator it = cameraInfos.begin();
    it != cameraInfos.end(); ++it)
        std::cout << it->description().toStdString().c_str() << std::endl; 


}

在此函数返回时发生崩溃。如果我这样做:

foreach(const QCameraInfo &ci, QCameraInfo::availableCameras());

崩溃发生在 foreach 循环的评估中。同样,如果我将QList&lt;QCameraInfo&gt; cameraInfos 声明为类中的一个字段,则当类被销毁时会发生崩溃。这由我的调用堆栈的输出验证:

    ntdll.dll!000000007750eef1()    Unknown
    kernel32.dll!00000000773c1a0a() Unknown
>   VideoCapture.exe!free(void * pBlock) Line 51    C
    VideoCapture.exe!QCameraInfo::`scalar deleting destructor'(unsigned int)    C++
    VideoCapture.exe!QList<QCameraInfo>::node_destruct(QList<QCameraInfo>::Node * from, QList<QCameraInfo>::Node * to) Line 484 C++
    VideoCapture.exe!QList<QCameraInfo>::dealloc(QListData::Data * data) Line 857   C++
    VideoCapture.exe!QList<QCameraInfo>::~QList<QCameraInfo>() Line 817 C++

我正在使用 Visual Studio 2013(显然是 Windows)。

【问题讨论】:

  • 你有 QApplication 实例化吗?
  • 是的。主应用程序是此窗口的父应用程序。这个想法是在 gui 的主窗口部分中按下按钮时实例化一个 videopanle 对象。您可能是正确的,视频面板缺少一些基础设施。我不太清楚添加它的正确方法。
  • 如您所见,它的基类是 QWidget(我注意到它没有 exec() 方法)。这应该是别的什么吗?
  • 错误似乎与环境不符,很难猜出到底缺少什么。尝试创建QList&lt;int&gt;,会不会崩溃?还要在 main 中运行您的最小代码,看看它是否有效
  • @Alexey 感谢您的出色建议!不幸的是, QList 工作正常。我尝试在 main 中创建 QList 并在退出时遇到同样的崩溃。

标签: c++ qt memory


【解决方案1】:

您需要自己编译 Qt,然后在调试器下运行您的测试用例并查看它在哪里崩溃。为此,您还需要一个最小的、独立的测试用例 - 这必须是问题的一部分 (SSCCE)。实际上,您更有可能在其他地方损坏内存,而您看到的故障是堆损坏的结果,而不是 Qt 错误。

侧边栏:您需要精通在 Qt Creator 中运行小示例。可以说,Qt Creator 附带的模板不是很好。你可以use this template,作为Other Projects->Simple qmake,快速制作原型。

在 OS X 10.9 和 Windows 10/VS 2015 上使用当前 Qt 上的 1 个摄像头,以下对我来说很好。您使用的 std::cout 是红鲱鱼,您也可以使用 qDebug()

// https://github.com/KubaO/stackoverflown/tree/master/questions/camlist-37603946
#include <QtWidgets>
#include <QtMultimedia>

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   QComboBox combo;
   QObject::connect(&combo, &QComboBox::currentTextChanged, [&]{
      std::cout << combo.currentText().toStdString() << std::endl;
   });
   for (auto const & info : QCameraInfo::availableCameras())
      combo.addItem(info.description());
   combo.show();
   return app.exec();
}

【讨论】:

  • 谢谢你。我已经剥离了除 main 之外的所有代码并将您的示例复制到其中。我在发布 QList 对象时遇到了同样的错误。当我打印出我发布的组合框的内容时,我也遇到了同样的指针问题:stackoverflow.com/questions/37669003/…。您可能是对的,这两个问题是同一个问题。我正在使用 Qt 5 for VS 2013 预构建二进制文件。我会尝试建立自己的,看看会发生什么。
  • 我应该说我对 C++ 的无知以至于我不知道如何从调试器中获取比我已经在这里报告的更多的信息。
【解决方案2】:

因此,在遵循 Kuba 的建议并使用新构建的 Qt 库在我的环境中运行他的测试程序后,我遇到了同样的错误。然后我有了一个好主意,那就是在release 模式而不是debug 下运行它。瞧,它完美地工作,新构建的 Qt5(x86,正如它发生的那样)和从 Qt 的下载页面获得的预构建二进制文件(64 位)。

似乎链接到 qt debug 库导致了这种行为。我现在正在调试模式下链接到非调试库,我很高兴——在大多数情况下——我仍然有点恼火,以 'd' 为后缀的 qt 库似乎无法正常工作我的系统。不过,我可以继续开发这个项目。

感谢所有评论和回答!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多