在Visual Studio 2008中返回QVariantList崩溃

时间:2011-07-01 12:23:41

标签: visual-studio-2008 qt crash

我们有一个函数可以将从C库中检索到的JSON对象转换为QVariants。除列表外,所有数据类型都可以正常工作---布尔值,数字,字符串,对象/映射。当函数返回一个列表时,由于“为RtlValidateHeap指定了无效地址”,它在函数退出时崩溃,我认为这意味着发生了双重释放。

以下代码演示了错误:

QVariant no_crash() {
    QVariantMap map;

    map["Hello"] = "world!";
    qDebug() << map;
    return map;
}
// QMap(("Hello", QVariant(QString, "world!") ) )

QVariant crash() {
    QVariantList list;

    list << "Hello world!";
    qDebug() << list;
    return list;
}
// (QVariant(QString, "Hello world!") )

我看过有关此内容的帖子,但它们似乎都与Visual Studio 2010有关,而且与Qt SDK的二进制版本不兼容。我从http://qt.nokia.com/downloads/sdk-windows-cpp下载的Qt 4.7.3尝试了这个。

当列表超出范围时发生崩溃;只要返回值在调用堆栈中传播回来,就不会发生崩溃。


感谢您的回答。

是的,我完全清楚编译器在返回另一个值时构造了一个QVariant,但我确信编译器隐式构造了一个同样好的QVarint,与我的显式编码相比: - )

从我提供的链接安装时,会安装MinGW和Visual Studio 2008的库。我已将\ Desktop \ Qt \ 4.7.3 \ msvc2008 \ lib添加到我的全局lib文件搜索路径,当我运行我的程序时,Visual Studio输出窗口仅列出来自\ Desktop \ Qt \ 4.7.3 \ msvc2008的DLL加载。

错误发生在msvcr90d.dll中,大概是第二次释放内存时。很难说,因为堆栈似乎被破坏了。

应用程序是一个相当大的应用程序,只有用C ++编写的GUI,其余的是C.这可能是一个问题吗?该程序加载msvcp90d.dll和msvcr90d.dll。

4 个答案:

答案 0 :(得分:2)

错误原因是解决方案中的各个项目链接到静态运行时,而Qt库链接到动态运行时。

我查看了20多个项目的配置以及未包含在解决方案中但已链接到的已经构建的项目的配置,结果发现即使一个静态链接到C运行时,应用程序也会崩溃。

您可以通过打开项目属性,导航到Configuration Properties-&gt; C / C ++并选择Code Generation来更改运行时。运行时库应该是用于Release目标的多线程DLL和用于调试目标的多线程调试DLL。

答案 1 :(得分:0)

您的方法签名是

QVariant crash()

您应该返回QVariant但不是 QVariant ,而是尝试返回 QVariantList ,这是QList <QVariant>的同义词

我认为你不能这样做。

在我看来,你甚至不能编译这个。也许这是你的问题?

答案 2 :(得分:0)

我看到了几个潜在的问题:

首先,您链接的SDK是MinGW编译器,而不是Visual Studio。您应该为编译器使用正确的SDK,或者从源代码重新编译Qt。对于VS2008,请转到此页面:http://qt.nokia.com/downloads/并下载“Qt Libraries for Windows - VS2008”。

您的代码确实编译:会发生的是返回包含QVariantMap或QVariantSet的QVariant。编译器正在为您构建QVariant。你的代码实际上在做什么:

QVariant no_crash() {
    QVariantMap map;

    map["Hello"] = "world!";
    qDebug() << map;
    return QVariant(map); // This returns a QVariant which contains a map of QVariants
}

QVariant crash() {
    QVariantList list;

    list << "Hello world!";
    qDebug() << list;
    return QVariant(list); // This returns a QVariant which contains a list of QVariants
}

这应该可行 - 我只是在这里编译它,它适用于我。你只需要在使用它时检查QVariant的类型(例如,在返回的QVariant上调用toString()将返回一个空字符串,因为它是你调用它的列表,而不是QVariant 列表中)

答案 3 :(得分:0)

确保C / C ++代码生成中的运行时库选项分别设置为调试和发布的多线程调试DLL(/ MDd)或多线程DLL(/ MD)。一些Qt类型QVariantMapQVariantListQModelIndexList可能与/ MD(在Qt的dll中)分配,当它们与/ MT(在应用程序中)解除分配时,我认为这会导致崩溃。这也可以解决QString::toStdWString()上的崩溃问题。为了将其链接起来,可以将忽略所有默认库设置为否,忽略特定库不应该提及Qt使用的crt dll。