2011-07-01 120 views
1

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

下面的代码演示了错误:

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添加到我的全局库文件搜索路径中,并且当我运行我的程序时,Visual Studio输出窗口仅列出来自\ Desktop \ Qt \ 4.7.3 \ msvc2008的DLL加载。

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

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

+0

我现在从源码构建Qt。一旦我尝试过,我会在这里添加评论。 –

回答

0

你的方法签名是

QVariant crash() 

您应该返回的QVariant但不是一个的QVariant你试图返回QVariantList这是QList <QVariant>

代名词,我不认为你可以这样做。

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

+0

QVariants可以容纳QVariantLists –

0

我看到一对夫妇的潜在问题:

首先,你链接到SDK是MinGW的编译器,而不是视觉工作室。您应该为您的编译器使用正确的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 列表)

+0

为了确保,我下载了Visual Studio版本。这是一个更快的下载和安装,但它导致了同样的崩溃。 –

+0

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

2

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

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

您可以通过打开项目的属性,导航到配置属性 - > C/C++并选择代码生成来更改运行时。运行时库应该是用于发布目标的多线程DLL和用于调试目标的多线程调试DLL。

0

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