2011-07-01 100 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。