Возвращение QVariantList в Visual Studio 2008 дает сбой - PullRequest
1 голос
/ 01 июля 2011

У нас есть функция, которая преобразует объекты JSON, полученные из библиотеки C, в 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. Я пробовал это с Qt 4.7.3, скачанной с http://qt.nokia.com/downloads/sdk-windows-cpp.

Сбой происходит, когда список выходит из области видимости; до тех пор, пока возвращаемое значение распространяется обратно в стек вызовов, сбоев не происходит.


Спасибо за ваши ответы.

Да, я полностью осознаю, что компилятор создает QVariant, когда я возвращаю другое значение, но я уверен, что компилятор неявно создает одинаково хороший QVarint по сравнению с тем, что было бы для меня явным кодированием: -)

При установке по предоставленной мной ссылке устанавливаются библиотеки как для MinGW, так и для Visual Studio 2008. Я добавил \ Desktop \ Qt \ 4.7.3 \ msvc2008 \ lib в мой глобальный путь поиска файлов lib, и когда я запускаю свою программу, в окне вывода Visual Studio отображаются только библиотеки DLL из \ Desktop \ Qt \ 4.7.3 \ msvc2008 как загружен.

Ошибка возникает в msvcr90d.dll, предположительно, когда память освобождается во второй раз. Трудно сказать, так как стек кажется разрушенным.

Приложение довольно большое, только с графическим интерфейсом, написанным на C ++, а остальное - C. Может ли это быть проблемой? Программа загружает как msvcp90d.dll, так и msvcr90d.dll.

Ответы [ 4 ]

2 голосов
/ 05 июля 2011

Ошибка оказалась в том, что отдельные проекты в решении были связаны со статическими средами выполнения, тогда как библиотеки Qt были связаны с динамическими средами исполнения.для уже созданных проектов, не включенных в решение, но связанных с ним, и оказалось, что, если даже один из них статически связан со средой выполнения C, приложение будет аварийно завершено., перейдя в Свойства конфигурации-> C / C ++ и выбрав Генерация кода.Библиотека времени выполнения должна быть многопоточной DLL для целей выпуска и многопоточной DLL отладки для целей отладки.

0 голосов
/ 22 апреля 2013

Убедитесь, что для параметра Runtime Library в C / C ++ Code Generation установлено значение Многопоточная отладочная DLL (/ MDd) или Многопоточная DLL (/ MD) соответственно для Отладки и Выпуска. Некоторые типы Qt, такие как QVariantMap, QVariantList, QModelIndexList, вероятно, выделяются с помощью / MD (в dll Qt), и когда они освобождаются с / MT (в приложении), я думаю, что это вызывает сбой. Это также может исправить падение на QString::toStdWString(). Чтобы это можно было связать, возможно, для Ignore All Default Library следует установить значение No, а Ignore Specific Library не должна упоминать библиотеки crt, используемые Qt.

0 голосов
/ 01 июля 2011

Я вижу пару потенциальных проблем:

Во-первых, SDK, на который вы ссылаетесь, предназначен для компилятора MinGW, а не для Visual Studio.Вы должны использовать правильный SDK для вашего компилятора или перекомпилировать Qt из исходного кода.Для VS2008 перейдите на эту страницу: http://qt.nokia.com/downloads/ и загрузите «Qt Libraries for Windows - VS2008».

Ваш код компилируется: в результате возвращается QVariant, который содержит QVariantMap или QVariantSet.Компилятор создает для вас 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, когда вы его используете (например, вызов toString () для возвращаемого QVariant вернет пустую строку, так как это список , который вы вызываете, а не QVariant в списке)

0 голосов
/ 01 июля 2011

Ваша подпись метода

QVariant crash()

Вы должны вернуть QVariant, но вместо QVariant вы пытаетесь вернуть QVariantList , который является синонимом QList <QVariant>

Я не думаю, что вы можете сделать это.

По моему мнению, вы даже не сможете скомпилировать это.Может это твоя проблема?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...