PDA

View Full Version : Release ok, debug crashes [compilable code]



Raccoon29
10th December 2009, 15:49
Hi everyone,

I'm here to provide you some fun :)
Take this code and paste it in a QPushButton::clicked() slot

mydb db1;
if(db1.open())
QMessageBox::information(this,"DEBUG info","Connected");
db1.close();
then paste this somewhere in the .h or .cpp as you prefer

class mydb{
private:
QVector<QSqlDatabase*> *handle;
public:
mydb(){ handle=new QVector<QSqlDatabase*>(); }
~mydb(){ delete handle; }
bool open()
{
QSqlDatabase handle=QSqlDatabase::addDatabase("QMYSQL","connName");
handle.setHostName("host");
handle.setDatabaseName("db");
handle.setUserName("username");
handle.setPassword("password");
handle.open();
this->handle->append(&handle);
return handle.isOpen();
}

void close()
{
QSqlDatabase *h=handle->at(0);
if(h->isValid())
qDebug() << "Valid";
if(h->isOpen())
qDebug() << "Open";
h->close();
handle->remove(0);
}
};
includes

#include <QtGui>
#include <QtSql>
// these are enhough, don't forget QT+=sql in file .pro
I'm compiling with mingw and running under Windows Xp SP3.
To me this code runs clearly in release and raises exception in debug.
Switching between modes with QtCreator causes it to change behavior.

I see nothing wrong in code... maybe you can notice something I'm missing.

Have fun :D

wysota
10th December 2009, 16:47
I see nothing wrong in code...

I do. You are assigning a pointer to a local object to a non-local variable thus your close() method is bound to crash the application.

Raccoon29
10th December 2009, 17:06
I do. You are assigning a pointer to a local object to a non-local variable thus your close() method is bound to crash the application.

Yes, but why it works -somehow- in release and crash in debug? An exception is an exception, isn't it?

S.wysota you were promoted from Guru to Master of Zen, congratulations, you worth it all! :)

wysota
10th December 2009, 17:46
Yes, but why it works -somehow- in release and crash in debug? An exception is an exception, isn't it?
It works because the debug version probably zeroes the stack memory it frees while release mode doesn't. So in the release mode the object is still there although formally it has been deallocated. In debug you either dereference a null object or the stack location is being overwritten by another data.

Raccoon29
10th December 2009, 17:57
It works because the debug version probably zeroes the stack memory it frees while release mode doesn't.

I see! So it becomes a sort of time bomb. Cute :)
Anyway this QSqlDatabase in 'mydb' class is providing me with several headaches.
What would be the correct way to write the above class? (which will hopefully close the thread)

wysota
11th December 2009, 00:26
You can always fetch the connection handler by name using a proper static method from QSqlDatabase. So all you need to store (if at all) is the connection name. Remember they have to be unique.

Raccoon29
16th December 2009, 15:15
You can always fetch the connection handler by name using a proper static method from QSqlDatabase. So all you need to store (if at all) is the connection name. Remember they have to be unique.

I read somewhere that this has performance influences; true? false? Who knows, anyway your solution seems to be the reason of everything.

< You fixed it?? How in the world... Saint not for joke! :D >

wysota
16th December 2009, 16:41
I read somewhere that this has performance influences; true? false?
Ask the guy who wrote it :)

Raccoon29
16th December 2009, 16:48
Ask the guy who wrote it :)

Smart :D