Some error occuring on destructor
-
Well... You are already using Qt's Model/View since you are using a QTableWidget.
From the QSqlQueryModel documentation:
QSqlQueryModel *model = new QSqlQueryModel; model->setQuery("SELECT name, salary FROM employee"); model->setHeaderData(0, Qt::Horizontal, tr("Name")); model->setHeaderData(1, Qt::Horizontal, tr("Salary")); QTableView *view = new QTableView; view->setModel(model); view->show();
Adapt that to the query you are using and you should be good to go.
-
@Ovidiu_GCO
I do not see anything obvious in the code you show or comment out which would lead to the error. Remember that when dealing with memory allocation issues, the route the code happens to follow can show up or hide a problem, so a change unrelated to a problem can cause it to occur or disappear.When you hit the assertion failure while running in the debugger, it should stop. There is a window with a "stack trace" of all the function calls leading to the assert. You should show us that output, it may contain function names which give a clue. This is a vital window in debugging, you want to find it.
Also since the assert is on destruction of
pickParticipants
object as a whole, you might also show us the calling code, where you create & destroy the instance?Are you quite sure that everything has been rebuilt from clean, as @mrjj suggested?
-
@JonB I am trying to use the View/Model approach now so I cannot post the stack trace yet, but I will if this approach won't work.
Here is the call:
//moving to the next screen "PickParticipants" //hide the "Add a new tournament" UI this->hide(); //set the new page "PickParticipants" pickParticipants pickParticipantsUI; pickParticipantsUI.setModal(true); //show the new page pickParticipantsUI.exec();
But there is no destruction on that UI...
And yes, I made a new project and copy-pasted the source code.
@SGaist I tried to use the code you posted, but it won't show the selection. There is no record in the table. Should I do something else?
Also, I think this approach won't work for me, because I need to put a checkbox on each table-row. Is this possible?
-
But there is no destruction on that UI...
Conceptually, you need to understand that when you declare a local/stack variable, like your
pickParticipants pickParticipantsUI;
, then just as there is an implicit construction even though you have no explicitnew
, so equally there is an implicit destruction when the local variable goes out of scope even though you have no explicitdelete
. I'm not sure whether you are aware of that.The most important thing you have not shown is the stack trace when the assertion occurs.
-
Sorry for the "long-time-no-answer", I've been really busy with other school projects, but I managed to work a little bit on the file.
I still have some heap corruption in it, but now it is occurring some other place.
pickParticipants.cpp:
#include "pickParticipants.h" #include <qtablewidget.h> #include <QtCore> #include <QtSql/qsqldatabase.h> #include <QtSql/qsqlquery.h> #include <QtSql/qsqlquerymodel.h> #include <qvector.h> #include <qstringlist.h> pickParticipants::pickParticipants(QWidget *parent) : QDialog(parent) { ui.setupUi(this); //Connect listeners connect(ui.deletePushButton, SIGNAL(clicked()), this, SLOT(deletePilot())); connect(ui.addPushButton, SIGNAL(clicked()), this, SLOT(addNewPilot_Button())); connect(ui.okPushButton, SIGNAL(clicked()), this, SLOT(updateTableStructure())); //Populate the table this->populatePilotsTable(); } pickParticipants::~pickParticipants() { QSqlDatabase::database("dataB").close(); } void pickParticipants::populatePilotsTable() { //Cleaning the table ui.driversTable->setRowCount(0); //Open the database and fetch table entries if (QSqlDatabase::database("dataB").open()) { //SQL Query that fetches all the pilots along with their team and car specs QString selectAllPilots("SELECT Piloti.nume, Echipe.nume, Masini.Serie_Sasiu, Masini.numar_masina, Masini.capacitate_motor, Masini.putere_motor FROM Piloti JOIN Echipe ON Piloti.ID_Echipa = Echipe.ID_Echipa JOIN Masini ON Piloti.ID_Pilot = Masini.ID_Pilot;"); //Execute "selectAllPilots" query against "dataB" database QSqlQuery qry(selectAllPilots, QSqlDatabase::database("dataB")); //Table row counter int rowCounter = 0; //Build drivers table while (qry.next()) { ui.driversTable->insertRow(rowCounter); //we use "ui.driversTable->columnCount() - 1" because last column is a checkbox for (int colCounter = 0; colCounter < ui.driversTable->columnCount() - 1; colCounter++) { ui.driversTable->setItem(rowCounter, colCounter, new QTableWidgetItem(qry.value(colCounter).toString())); } //TO-DO insert the checkbox in the last column QTableWidgetItem *checkBoxItem = new QTableWidgetItem(); checkBoxItem->setCheckState(Qt::Unchecked); ui.driversTable->setItem(rowCounter, ui.driversTable->columnCount() - 1, checkBoxItem); //move to the next row rowCounter++; } qry.finish(); qry.~QSqlQuery(); } } void pickParticipants::addNewPilot_Button() { //Set up the window addNewPilot addPilotWindow; addPilotWindow.setModal(true); //Show the window addPilotWindow.exec(); } void pickParticipants::deletePilot() { int selectedRow; for (QTableWidgetItem* selectedItem : ui.driversTable->selectedItems()) { if ((*selectedItem).isSelected()) { selectedRow = (*selectedItem).row(); break; } } //Delete car from database using selected row QString deleteCar("DELETE FROM Masini WHERE Serie_sasiu = '" + (ui.driversTable->item(selectedRow, 2))->text() + "';"); QSqlQuery deleteFromCar(deleteCar, QSqlDatabase::database("dataB")); deleteFromCar.finish(); //Delete pilot from database using selected row QString deletePilot("DELETE FROM Piloti WHERE nume = '" + (ui.driversTable->item(selectedRow, 0))->text().split(' ').value(0) + "' AND prenume = '" + (ui.driversTable->item(selectedRow, 0))->text().split(' ').value(1) + "';"); QSqlQuery deleteFromPilots(deletePilot, QSqlDatabase::database("dataB")); deleteFromPilots.finish(); } //Function to update table's structure void pickParticipants::updateTableStructure() { //Saving drivers' IDs before clearing the table this->saveDrivers(); //Clearing view, including headers and selections ui.driversTable->clear(); //Setting up the new structure this->setRaceTableStructure(); //Setting the number of labels ui.driversTable->setColumnCount(4); //Inserting the labels ui.driversTable->setHorizontalHeaderLabels(labelList); //Connecting the listeners to race-related functions connect(ui.deletePushButton, SIGNAL(clicked()), this, SLOT(deleteRace())); connect(ui.addPushButton, SIGNAL(clicked()), this, SLOT(addNewRaceFcn())); connect(ui.okPushButton, SIGNAL(clicked()), this, SLOT(openResults())); labelList.~QStringList(); //Populating the table with races this->populateRacesTable(); } // Races part void pickParticipants::addNewRaceFcn() { //Set up the window addNewRace addRaceWindow; addRaceWindow.setModal(true); //Show the window addRaceWindow.exec(); } void pickParticipants::deleteRace() { int selectedRow; for (QTableWidgetItem* selectedItem : ui.driversTable->selectedItems()) { if ((*selectedItem).isSelected()) { selectedRow = (*selectedItem).row(); break; } } //Delete car from database using selected row QString deleteRace("DELETE FROM Curse WHERE locatie = '" + (ui.driversTable->item(selectedRow, 0))->text() + "' AND lungime = " + (ui.driversTable->item(selectedRow, 0))->text() + ";"); QSqlQuery deleteFromRaces(deleteRace, QSqlDatabase::database("dataB")); deleteFromRaces.finish(); } void pickParticipants::openResults() { this->saveRaces(); //moving to the next screen "resultPage" //hide the "Pick Races" UI this->hide(); //set the new page "PickParticipants" resultPage resultPageUI; resultPageUI.setModal(true); //show the new page resultPageUI.exec(); } void pickParticipants::populateRacesTable() { //Cleaning the table ui.driversTable->setRowCount(0); //Open the database and fetch table entries if (QSqlDatabase::database("dataB").open()) { //SQL Query that fetches all the pilots along with their team and car specs QString selectAllRaces("SELECT locatie, numar_ture, lungime FROM Curse;"); //Execute "selectAllPilots" query against "dataB" database QSqlQuery qry(selectAllRaces, QSqlDatabase::database("dataB")); //Count the number of records int rowCounter = 0; qry.first(); //Build drivers table while (qry.next()) { ui.driversTable->insertRow(rowCounter); //we use "ui.driversTable->columnCount() - 1" because last column is a checkbox for (int colCounter = 0; colCounter < ui.driversTable->columnCount() - 1; colCounter++) { ui.driversTable->setItem(rowCounter, colCounter, new QTableWidgetItem(qry.value(colCounter).toString())); } //TO-DO insert the checkbox in the last column QTableWidgetItem* checkboxItem = new QTableWidgetItem(); checkboxItem->setCheckState(Qt::Unchecked); ui.driversTable->setItem(rowCounter, ui.driversTable->columnCount() - 1, checkboxItem); //move to the next row rowCounter++; } qry.finish(); } } //Function to save selected drivers' IDs in vector void pickParticipants::saveDrivers() { //Query to fetch driver's Id using name QString selectDriverIdByName("SELECT ID_Pilot FROM Piloti WHERE nume = '"); for (int rowIterator = 0; rowIterator < ui.driversTable->rowCount(); rowIterator++) { if (ui.driversTable->item(rowIterator, ui.driversTable->columnCount() - 1)->checkState()) { //Pick every driver with checkbox's checkState == 'Checked'(2) //Fetching driver's name from the table QString driverName = ui.driversTable->item(rowIterator, 0)->text() + "';"; //Fetching ID from the database and appending it in the drivers' vector QSqlQuery qry(selectDriverIdByName + driverName, QSqlDatabase::database("dataB")); qry.first(); driversIdVector.append(qry.value(0).toInt()); qry.~QSqlQuery(); } } } //Function to save selected races' IDs in vector void pickParticipants::saveRaces() { //Query to fetch driver's Id using name QString selectRaceIdByLocation("SELECT ID_Cursa FROM Curse WHERE locatie = '"); for (int rowIterator = 0; rowIterator < ui.driversTable->rowCount(); rowIterator++) { if (ui.driversTable->item(rowIterator, ui.driversTable->columnCount() - 1)->checkState() == 2) { //Pick every race with checkbox's checkState == 'Checked'(2) //Fetching race's location from the table QString raceLocation = ui.driversTable->item(rowIterator, 0)->text() + "';"; //Fetching ID from the database and appending it in the race' vector QSqlQuery qry(selectRaceIdByLocation + raceLocation, QSqlDatabase::database("dataB")); qry.first(); racesIdVector.append(qry.value(0).toInt()); raceLocation.~QString(); } } } void pickParticipants::setRaceTableStructure() { //Label list for the Races Table QStringList labelList = { "Location", "Laps", "Length", "To Tournament" }; //Setting the number of labels ui.driversTable->setColumnCount(4); //Inserting the labels ui.driversTable->setHorizontalHeaderLabels(labelList); //Connecting the listeners to race-related functions connect(ui.deletePushButton, SIGNAL(clicked()), this, SLOT(deleteRace())); connect(ui.addPushButton, SIGNAL(clicked()), this, SLOT(addNewRaceFcn())); connect(ui.okPushButton, SIGNAL(clicked()), this, SLOT(openResults())); labelList.~QStringList(); }
The error is shown on
this->setRaceTableStructure();
inside thevoid pickParticipants::updateTableStructure()
method.Call stack:
ntdll.dll!RtlpBreakPointHeap() Unknown ntdll.dll!RtlpValidateHeapEntry() Unknown ntdll.dll!RtlValidateHeap() Unknown KernelBase.dll!HeapValidate() Unknown ucrtbased.dll!_CrtIsValidHeapPointer(const void * block) Line 1407 C++ ucrtbased.dll!free_dbg_nolock(void * const block, const int block_use) Line 904 C++ ucrtbased.dll!_free_dbg(void * block, int block_use) Line 1030 C++ ucrtbased.dll!free(void * block) Line 32 C++ Qt5Cored.dll!00007ff899c90265() Unknown Qt5Cored.dll!00007ff899bf612e() Unknown Qt5Cored.dll!00007ff899bedac4() Unknown Qt5Cored.dll!00007ff899c511e7() Unknown Qt5Cored.dll!00007ff89a0c4e7a() Unknown Qt5Cored.dll!00007ff89a0cfcba() Unknown Qt5Cored.dll!00007ff89a0b8910() Unknown Qt5Cored.dll!00007ff89a0bfffc() Unknown Qt5Cored.dll!00007ff89a0aaf5e() Unknown Qt5Cored.dll!00007ff89a0a57f3() Unknown Qt5Widgetsd.dll!00007ff89b31171b() Unknown Qt5Widgetsd.dll!00007ff89b312527() Unknown Qt5Widgetsd.dll!00007ff89b31396a() Unknown Qt5Widgetsd.dll!00007ff89b314370() Unknown Qt5Widgetsd.dll!00007ff89b31168f() Unknown Qt5Widgetsd.dll!00007ff89b331686() Unknown F1_System.exe!QTableWidgetItem::`scalar deleting destructor'(unsigned int) C++ Qt5Widgetsd.dll!00007ff89b339915() Unknown Qt5Widgetsd.dll!00007ff89b339837() Unknown Qt5Widgetsd.dll!00007ff89b334e29() Unknown > F1_System.exe!pickParticipants::updateTableStructure() Line 109 C++ F1_System.exe!pickParticipants::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 90 C++ [External Code] F1_System.exe!addNewTournament::openPilotsTeamsCars() Line 35 C++ F1_System.exe!addNewTournament::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 77 C++ [External Code] F1_System.exe!welcomePage::openAddNewTournamentWindow() Line 24 C++ F1_System.exe!welcomePage::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 78 C++ [External Code] F1_System.exe!F1_System::validateLogin() Line 40 C++ F1_System.exe!F1_System::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 76 C++ [External Code] F1_System.exe!main(int argc, char * * argv) Line 9 C++ F1_System.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 104 C++ [External Code]
Please, I really need some help on this...
Thank you for your time!
-
@Ovidiu_GCO said in Some error occuring on destructor:
qry.~QSqlQuery();
Why?!
"labelList.~QStringList();" - again - Why?
You should not call destructors like this (this is usually only done when using placement new). A destructor is called AUTOMATICALLY when the variable is destroyed. -
@Ovidiu_GCO What is in this line:
"pickParticipants::updateTableStructure() Line 109" -
hi @Ovidiu_GCO ,
can you tell mywaywhy your ui - instance is created on the stack and not the heap ? Seems like it was created automatically via QtCreator, if thats the case it is highly unusual behaviour. -
@Ovidiu_GCO
ah alright, you made the ui form independet from your class and than added it afterwards, alright.PS. thanks, fixed the obvious typo :P