PDA

View Full Version : Crash on function exit (destructor) while using QVariantList with VS2010 ?



VS2k10_qt
23rd April 2011, 00:03
Hello all, it seems that when this is compiled with VS2010, it crashes at the destructor call, as can be seen by the stack dump:


msvcr100d.dll!operator delete(void * pUserData) Line 52 + 0x51 bytes C++
> testini.exe!QVariant::`scalar deleting destructor'() + 0x46 bytes C++
testini.exe!QList<QVariant>::node_destruct(QList<QVariant>::Node * from, QList<QVariant>::Node * to) Line 418 + 0x3e bytes C++
testini.exe!QList<QVariant>::free(QListData::Data * data) Line 744 C++
testini.exe!QList<QVariant>::~QList<QVariant>() Line 718 C++
testini.exe!WzConfig::vector2i(const QString & name) Line 65 + 0x1d bytes C++
testini.exe!main(int argc, char * * argv) Line 82 + 0x31 bytes C++



The code in question looks like (it crashes on exit of this function):


Vector2i WzConfig::vector2i(const QString &name)
{
Vector2i r;
ASSERT_OR_RETURN(r, contains(name), "Missing %s", name.toUtf8().constData());
QVariantList v = value(name).toList();
ASSERT(v.size() == 2, "Bad list of %s", name.toUtf8().constData());
r.x = v[0].toInt();
r.y = v[1].toInt();
return r;
}




int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

{
WzConfig ini("test.ini");
ini.setVector2i("test", Vector2i(1, 2));
ini.setVector3i("test2", Vector3i(1, 2, 3));
ini.setVector3f("test3", Vector3f(1, 2, 3));
ini.setVector3f("test3", Vector3i(1, 2, 3));
ini.setVector3i("test3", Rotation(1, 2, 3));
}
{
WzConfig ini("test.ini");
Vector2i v = ini.vector2i("test");
qWarning("x = %d, y = %d", v.x, v.y);
}

return 0;
}




struct Vector2i
{
Vector2i() {}
Vector2i(int x, int y) : x(x), y(y) {}

int x, y;
};


class WzConfig : public QSettings
{
Q_OBJECT

public:
WzConfig(const QString &name, QObject *parent = 0) : QSettings(QString("test.ini"), QSettings::IniFormat, parent) { Q_UNUSED(name); }
Vector3f vector3f(const QString &name);
void setVector3f(const QString &name, const Vector3f &v);
Vector3i vector3i(const QString &name);
void setVector3i(const QString &name, const Vector3i &v);
Vector2i vector2i(const QString &name);
void setVector2i(const QString &name, const Vector2i &v);
};


Does anyone know if this is a Qt bug (version 4.7.2) or is this a compiler bug (VS 2k10)--it don't seem to crash on linux, or are we doing something wrong ?
Note: VS2k10 was used to compile 4.7.2 libs, since that isn't made available yet on Qt's main site)

Thanks for the info.

VS2k10_qt
24th April 2011, 03:16
If I change the above code to this


Vector2i WzConfig::vector2i(const QString &name)
{
Vector2i r;
ASSERT_OR_RETURN(r, contains(name), "Missing %s", name.toUtf8().constData());
QStringList v = value(name).toStringList();
ASSERT(v.size() == 2, "Bad list of %s", name.toUtf8().constData());
r.x = v[0].toInt();
r.y = v[1].toInt();
return r;
}

Then I don't get any crashes.

So it is a problem with QVariantList for some reason.

DanH
25th April 2011, 02:17
What does method value() do??

The basic problem is that QVariantList is attempting to destruct the objects it "owns", and one of those has already been destructed. Scenarios like this may work or not work, depending on the precise order that things appear in the "child" chain.

I suspect your problem is in your implementations of value() and toList().

VS2k10_qt
25th April 2011, 03:40
What does method value() do??

The basic problem is that QVariantList is attempting to destruct the objects it "owns", and one of those has already been destructed. Scenarios like this may work or not work, depending on the precise order that things appear in the "child" chain.

I suspect your problem is in your implementations of value() and toList().

Hmm?

It is:
class WzConfig : public QSettings
ie, Qsettings::value().toList().
And value is defined as:
QVariant value ( const QString & key, const QVariant & defaultValue = QVariant() ) const