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 query
line. How to fix? -
@Emon-Haque Why is a pointer necessary? Change
QSqlQuery *query
toQSqlQuery query
in .h, and then makequery = QSqlQuery("SELECT * FROM sqlite_master", db);
, thus avoiding these unnecessary problems. -
@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
query
is valid before trying to delete it. -
@Emon-Haque
As @Pl45m4 has commented. Yourquery
is 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.... -
@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
qDebug
output:deleting 0x0 deleted deleting 0x41a5c00 deleted deleting 0x41a59e0 deleted
first, I attached
quran.db
and it deleted anullptr
? I didn't calldb.Open()
anywhere, this is the only function where I calldb.Open()
. Looks likedb.isOpen()
returnedtrue
although I didn't callOpen()
. For the rest two database I attached, it got something to delete. -
@Emon-Haque Why is a pointer necessary? Change
QSqlQuery *query
toQSqlQuery query
in .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. -
@eyllanesc, can you change the database of such
query
variable 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.
-
@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
In your code, if when you enterObjectsView::openFileDialog()
db
is already open butquery
is a member variable and uninitialised it will crash. Initialise member variables before first use.I also said that for safety you should
query = nullptr
immediately afterdelete query
, to prevent accidental re-deletion.If you
delete
it anywhere else it will also crash here.Finally, if nothing works. I don't know about this, but when you create
query
you associate it withdb
at that time. I do not know if you close or changedb
whether that could cause a problem when you laterdelete query
associated with a now-closed-or-differentdb
.Frankly the whole business of deleting
query
only next time you open/createdb
is "messy". And it doesn't solve what happens to allocatedquery
if you never come toopenFileDialog()
again. Do you need to do things this way? -
@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
nullptr
after youdelete
a 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 globalisConnected
to see whether it crashes with that or not.