Why does the app crashes on delete QSqlQuery*
-
Here's what I've now:
void ObjectsView::openFileDialog(){ QFileDialog dialog; if(!dialog.exec()) return; if(db.isOpen()) { db.close(); qDebug() << "deleting"; delete query; qDebug() << "deleted"; } auto widget = qobject_cast<QueryWidget*>(parent()->parent()); fileName = dialog.selectedFiles().first(); db.setDatabaseName(fileName); db.open(); query = new QSqlQuery("SELECT * FROM sqlite_master", db); query->setForwardOnly(true); if(!query->exec()){ emit widget->logMessage("e,Could not connect to " + fileName); //e, for error return; } makeTree(); emit widget->logMessage("s,Connected to " + fileName); // s, for success isConnected = true; }With these it doesn't crash always. When it does, I see it printing
deleting, so it crashes for thisdelete queryline. How to fix? -
Here's what I've now:
void ObjectsView::openFileDialog(){ QFileDialog dialog; if(!dialog.exec()) return; if(db.isOpen()) { db.close(); qDebug() << "deleting"; delete query; qDebug() << "deleted"; } auto widget = qobject_cast<QueryWidget*>(parent()->parent()); fileName = dialog.selectedFiles().first(); db.setDatabaseName(fileName); db.open(); query = new QSqlQuery("SELECT * FROM sqlite_master", db); query->setForwardOnly(true); if(!query->exec()){ emit widget->logMessage("e,Could not connect to " + fileName); //e, for error return; } makeTree(); emit widget->logMessage("s,Connected to " + fileName); // s, for success isConnected = true; }With these it doesn't crash always. When it does, I see it printing
deleting, so it crashes for thisdelete queryline. How to fix?@Emon-Haque Why is a pointer necessary? Change
QSqlQuery *querytoQSqlQuery queryin .h, and then makequery = QSqlQuery("SELECT * FROM sqlite_master", db);, thus avoiding these unnecessary problems. -
Here's what I've now:
void ObjectsView::openFileDialog(){ QFileDialog dialog; if(!dialog.exec()) return; if(db.isOpen()) { db.close(); qDebug() << "deleting"; delete query; qDebug() << "deleted"; } auto widget = qobject_cast<QueryWidget*>(parent()->parent()); fileName = dialog.selectedFiles().first(); db.setDatabaseName(fileName); db.open(); query = new QSqlQuery("SELECT * FROM sqlite_master", db); query->setForwardOnly(true); if(!query->exec()){ emit widget->logMessage("e,Could not connect to " + fileName); //e, for error return; } makeTree(); emit widget->logMessage("s,Connected to " + fileName); // s, for success isConnected = true; }With these it doesn't crash always. When it does, I see it printing
deleting, so it crashes for thisdelete queryline. How to fix?@Emon-Haque said in Why does the app crashes on delete QSqlQuery*:
When it does, I see it printing deleting, so it crashes for this delete query line. How to fix?
Looks like a segfault. You're probably accessing
query(i.e. trying to delete it) when there wasn't created a query object before, so it's still null.Check if
queryis valid before trying to delete it. -
Here's what I've now:
void ObjectsView::openFileDialog(){ QFileDialog dialog; if(!dialog.exec()) return; if(db.isOpen()) { db.close(); qDebug() << "deleting"; delete query; qDebug() << "deleted"; } auto widget = qobject_cast<QueryWidget*>(parent()->parent()); fileName = dialog.selectedFiles().first(); db.setDatabaseName(fileName); db.open(); query = new QSqlQuery("SELECT * FROM sqlite_master", db); query->setForwardOnly(true); if(!query->exec()){ emit widget->logMessage("e,Could not connect to " + fileName); //e, for error return; } makeTree(); emit widget->logMessage("s,Connected to " + fileName); // s, for success isConnected = true; }With these it doesn't crash always. When it does, I see it printing
deleting, so it crashes for thisdelete queryline. How to fix? -
@Emon-Haque said in Why does the app crashes on delete QSqlQuery*:
When it does, I see it printing deleting, so it crashes for this delete query line. How to fix?
Looks like a segfault. You're probably accessing
query(i.e. trying to delete it) when there wasn't created a query object before, so it's still null.Check if
queryis valid before trying to delete it.@Pl45m4, in the constructor, I don't do anything with the
query, for thedb, I have only one line:db = QSqlDatabase::addDatabase("QSQLITE");I changed that
qDebug() << "deleting";toqDebug() << "deleting" << query;. Here's, without a crash, what I did:
and here's the
qDebugoutput:deleting 0x0 deleted deleting 0x41a5c00 deleted deleting 0x41a59e0 deletedfirst, I attached
quran.dband it deleted anullptr? I didn't calldb.Open()anywhere, this is the only function where I calldb.Open(). Looks likedb.isOpen()returnedtruealthough I didn't callOpen(). For the rest two database I attached, it got something to delete. -
@Emon-Haque
As @Pl45m4 has commented. Yourqueryis a member variable, so what do you initialise it to before you call this method for the first time?!Also, after you go
delete query;please set it tonullptr, to avoid any future re-deletes....@JonB, do I've to initialize it in constructor? I check whether the
db.isOpen(), if it is opened, it should get into that block BUT, to me, it looks like it's getting into that block when thedbis not open. -
Here's what I've now:
void ObjectsView::openFileDialog(){ QFileDialog dialog; if(!dialog.exec()) return; if(db.isOpen()) { db.close(); qDebug() << "deleting"; delete query; qDebug() << "deleted"; } auto widget = qobject_cast<QueryWidget*>(parent()->parent()); fileName = dialog.selectedFiles().first(); db.setDatabaseName(fileName); db.open(); query = new QSqlQuery("SELECT * FROM sqlite_master", db); query->setForwardOnly(true); if(!query->exec()){ emit widget->logMessage("e,Could not connect to " + fileName); //e, for error return; } makeTree(); emit widget->logMessage("s,Connected to " + fileName); // s, for success isConnected = true; }With these it doesn't crash always. When it does, I see it printing
deleting, so it crashes for thisdelete queryline. How to fix?@Emon-Haque Why is a pointer necessary? Change
QSqlQuery *querytoQSqlQuery queryin .h, and then makequery = QSqlQuery("SELECT * FROM sqlite_master", db);, thus avoiding these unnecessary problems. -
Hi,
@Emon-Haque said in Why does the app crashes on delete QSqlQuery*:
How to fix?
In the case of QSqlQuery: do not create it on the heap. There's no reason for that.
If you look at all the code related to QSqlQuery, you can see that none of them allocate it on the heap. -
@Emon-Haque Why is a pointer necessary? Change
QSqlQuery *querytoQSqlQuery queryin .h, and then makequery = QSqlQuery("SELECT * FROM sqlite_master", db);, thus avoiding these unnecessary problems.@eyllanesc, can you change the database of such
queryvariable later?EDIT
I did try that approach and at that time I got some error. Now, I don't have any, I'll go with that, Thanks. -
@eyllanesc, can you change the database of such
queryvariable later?EDIT
I did try that approach and at that time I got some error. Now, I don't have any, I'll go with that, Thanks.@Emon-Haque Your question is unclear. If you don't pass a QSqlDatabase to QSqlQuery then it will use the default database.
-
@Emon-Haque Your question is unclear. If you don't pass a QSqlDatabase to QSqlQuery then it will use the default database.
@eyllanesc, it can't be changed later. I've to reassign
query = QSqlQuery("SELECT * FROM sqlite_master", db);everytime. Not a problem, I think. -
@JonB, do I've to initialize it in constructor? I check whether the
db.isOpen(), if it is opened, it should get into that block BUT, to me, it looks like it's getting into that block when thedbis not open.@Emon-Haque
In your code, if when you enterObjectsView::openFileDialog()dbis already open butqueryis a member variable and uninitialised it will crash. Initialise member variables before first use.I also said that for safety you should
query = nullptrimmediately afterdelete query, to prevent accidental re-deletion.If you
deleteit anywhere else it will also crash here.Finally, if nothing works. I don't know about this, but when you create
queryyou associate it withdbat that time. I do not know if you close or changedbwhether that could cause a problem when you laterdelete queryassociated with a now-closed-or-differentdb.Frankly the whole business of deleting
queryonly next time you open/createdbis "messy". And it doesn't solve what happens to allocatedqueryif you never come toopenFileDialog()again. Do you need to do things this way? -
@eyllanesc, it can't be changed later. I've to reassign
query = QSqlQuery("SELECT * FROM sqlite_master", db);everytime. Not a problem, I think.@Emon-Haque said in Why does the app crashes on delete QSqlQuery*:
@eyllanesc, it can't be changed later. I've to reassign query = QSqlQuery("SELECT * FROM sqlite_master", db); everytime. Not a problem, I think.
Just what is waiting to trip someone up when the code gets changed at a later date. Things like "set to
nullptrafter youdeletea member variable" is just good practice. -
@Emon-Haque said in Why does the app crashes on delete QSqlQuery*:
@eyllanesc, it can't be changed later. I've to reassign query = QSqlQuery("SELECT * FROM sqlite_master", db); everytime. Not a problem, I think.
Just what is waiting to trip someone up when the code gets changed at a later date. Things like "set to
nullptrafter youdeletea member variable" is just good practice.@JonB, later after a break, I'll try with a global
QSqlQuery*again and will try to use that in other view, where I've usedQSqlQueryModel testModel(in previous post), to execute multiple statements AND instead ofdb.isOpen(), I'll use my globalisConnectedto see whether it crashes with that or not.