kaputter Heap: double free or corruption (out) beim löschen des Objektes
-
Hallo an alle,
ich bekomme immer einen Pointerfehler, wenn ich ein Objekt löschen möchte, nur finde ich den nicht.
Kann mir bitte jemand mit ein paar zusätzlichen Augen, und mehr Erfahrung/Wissen helfen?Ich erstelle in einer Funktion ein Objekt auf dem Heap.
ViewQuerryOption *newView= new ViewQuerryOption(); newView->tableViewOption(&querry, &viewName, &TqmStorage);
Das möchte ich am Ende der Funktion nun wie folgt löschen.
delete newView;
Nur leider bekomme ich an der Stelle, genauer beim Destruktor des Objekts, einen Pointer Fehler [...] "double free or corruption (out)" [...]
Durch googeln nach diesem Fehler finde ich zahlreiche Beispiele wie ich mir noch so den Speicher zerschießen kann, nur nichts was ich adaptieren kann, zumindest seh ich es nicht.Hier der Code zu "ViewQuerryOption.h"
#ifndef VIEWQUERRYOPTION_H #define VIEWQUERRYOPTION_H #include "MainTable.h" #include "ModulQuery.h" #include <QWidget> #include <QtGui> #include <QMap> using namespace std; class ViewQuerryOption : public QDialog { Q_OBJECT public: explicit ViewQuerryOption(QWidget *parent = 0); ~ViewQuerryOption(); void tableViewOption(QString *querry, QString *viewName, QMap <QString, ModulQuery> *TqmStorage); private: MainTable *ptrAufTable; QCheckBox plz; QCheckBox number; QCheckBox city; QCheckBox street; QCheckBox firstName; QCheckBox lastName; QCheckBox male; QCheckBox roll; QCheckBox companyName; QCheckBox phone; QCheckBox mail; QRadioButton rbUser; QRadioButton rbFirma; QRadioButton rbInstanz; QComboBox whereSelect; QComboBox relation; QLineEdit searcher; QLineEdit nameOfV; QVBoxLayout vBoxLall; QVBoxLayout vRadioL; QVBoxLayout vBoxLaddress; QVBoxLayout vBoxLinstanz; QVBoxLayout vBoxLnext; QVBoxLayout vBoxLcontact; QVBoxLayout vL; QVBoxLayout vButtonNemaL; QHBoxLayout hWhereL; QHBoxLayout hInAnL; QHBoxLayout hNeCoL; QHBoxLayout hL; QHBoxLayout hViewLabelL; QHBoxLayout hFunctionButtonL; QPushButton ok; QPushButton cancel; QGroupBox preSelect; QGroupBox selectViews; QGroupBox selectWhere; QGroupBox nameLabel; QLabel addressData; QLabel instanzData; QLabel nextData; QLabel contectData; QLabel nameOfView; QSignalMapper signalMapper; QString *makingQuery; QString *localViewName; QMap <QString, ModulQuery> *localTmpMap; QMessageBox msgBox; signals: public slots: void okPushed(); void createQuery(); void addToComboBox(const int &CheckBoxName); }; #endif // VIEWQUERRYOPTION_H
Hier der Code des Objektes "ViewQuerryOption.cpp"
#include "ViewQuerryOption.h" ViewQuerryOption::ViewQuerryOption(QWidget *parent) : QDialog(parent) { //Erzeugung aller grafischen bestandteile des fensteres und verschachtelung in Layouts //Hinzufügen der Objete, deren Signale gebündelt werden signalMapper.setMapping(&plz,1); signalMapper.setMapping(&number,2); signalMapper.setMapping(&city,3); signalMapper.setMapping(&street,4); signalMapper.setMapping(&firstName,5); signalMapper.setMapping(&lastName,6); signalMapper.setMapping(&male,7); signalMapper.setMapping(&roll,8); signalMapper.setMapping(&companyName,9); signalMapper.setMapping(&phone,10); signalMapper.setMapping(&mail,11); // Beschriftung der RadioButton rbInstanz.setText("Instanz / Person"); rbFirma.setText("Firma"); rbUser.setText("D-Manager Nutzer"); // vertikales Layout für die Radiobutton in der oberen GroupBox vRadioL.addWidget(&rbInstanz); vRadioL.addWidget(&rbFirma); vRadioL.addWidget(&rbUser); //Fügt der GroupBox das Layout mit den 3 RadioButton hinzu preSelect.setLayout(&vRadioL); // Beschriftung der Labels addressData.setText("Adressdaten"); instanzData.setText("Instanz / Personendaten"); nextData.setText("weitere Informationen"); contectData.setText("Kontaktdaten"); nameOfView.setText("Name der View:"); // Beschriftung der CheckBoxen street.setText("Strasse"); number.setText("Hausnummer"); plz.setText("Postleitzahl"); city.setText("Stadt"); male.setText("Anrede"); lastName.setText("Nachname"); firstName.setText("Vorname"); companyName.setText("Firmenname"); roll.setText("Instanzname"); phone.setText("Telefon"); mail.setText("E-Mail"); // vertikales Layout für die Checkboxen zur Adresse vBoxLaddress.addWidget(&addressData); vBoxLaddress.addWidget(&street); vBoxLaddress.addWidget(&number); vBoxLaddress.addWidget(&plz); vBoxLaddress.addWidget(&city); // vertikales Layout für die Checkboxen zur Instanz vBoxLinstanz.addWidget(&instanzData); vBoxLinstanz.addWidget(&male); vBoxLinstanz.addWidget(&lastName); vBoxLinstanz.addWidget(&firstName); // Horizontales Layout für die vertikalen Layouts der Checkboxen zur Adresse und Instanz hInAnL.addLayout(&vBoxLinstanz); hInAnL.addLayout(&vBoxLaddress); // vertikales Layout für die Checkboxen zur weiteren Daten vBoxLnext.addWidget(&nextData); vBoxLnext.addWidget(&companyName); vBoxLnext.addWidget(&roll); // vertikales Layout für die Checkboxen zur Kontaktdaten vBoxLcontact.addWidget(&contectData); vBoxLcontact.addWidget(&phone); vBoxLcontact.addWidget(&mail); // vertikales Layout für die Radiobutton in der mittleren GroupBox hNeCoL.addLayout(&vBoxLnext); hNeCoL.addLayout(&vBoxLcontact); // Fügt die 2 horizontalen layouts nochmal i ein vertikales zusammen vBoxLall.addLayout(&hNeCoL); vBoxLall.addLayout(&hInAnL); //Fügt der mittleren GroupBox das Layout mit den CheckBoxen hinzu selectViews.setLayout(&vBoxLall); //Fügt den Comboboxen die Standard Auswahlmöglichkeiten hinzu whereSelect.addItem("Suche verfeinern"); relation.addItem("="); relation.addItem("<"); relation.addItem(">"); // vertikales Layout für die untere Filtefunktion hWhereL.addWidget(&whereSelect); hWhereL.addWidget(&relation); hWhereL.addWidget(&searcher); // fügt layout GroupBox hinzu selectWhere.setLayout(&hWhereL); // Button vorbereiten ok.setText("OK"); cancel.setText("Abbrechen"); //Namenslabel und Funktionsbutten zu einem Layout formen hViewLabelL.addWidget(&nameOfView); hViewLabelL.addWidget(&nameOfV); hFunctionButtonL.addWidget(&ok); hFunctionButtonL.addWidget(&cancel); vButtonNemaL.addLayout(&hViewLabelL); vButtonNemaL.addLayout(&hFunctionButtonL); nameLabel.setLayout(&vButtonNemaL); // Fügt die 3 Groupboxen eine horizontalen Layout hinzu hL.addWidget(&preSelect); hL.addWidget(&selectViews); vL.addLayout(&hL); vL.addWidget(&selectWhere); vL.addWidget(&nameLabel); // Setzt das gesammte Layout setLayout(&vL); QObject::connect(&ok,SIGNAL(clicked()),this,SLOT(okPushed())); QObject::connect(&cancel,SIGNAL(clicked()),this,SLOT(close())); //Immer wenn eine Checkbox angeklickt wurde und sich damit ihr Status geänder hatte wird diese CheckBox //in den Mappere geschrieben QObject::connect( &plz, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &number, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &city, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &street, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &firstName, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &lastName, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &male, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &roll, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &companyName, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &phone, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect( &mail, SIGNAL(clicked()), &signalMapper, SLOT(map()) ); QObject::connect(&signalMapper, SIGNAL(mapped(const int&)), this, SLOT(addToComboBox(const int &)) ); } ViewQuerryOption::~ViewQuerryOption() { } //fügt die angehakten spalten zur ComboBox hinzu um diese weiter zu nutzen. void ViewQuerryOption::addToComboBox(const int &CheckBoxName) { switch (CheckBoxName) { case 1 : if (plz.isChecked()) { whereSelect.addItem("PLZ"); }else { whereSelect.removeItem(whereSelect.findText("PLZ")); } break; case 2 : if (number.isChecked()) { whereSelect.addItem("Hausnummer"); }else { whereSelect.removeItem(whereSelect.findText("Hausnummer")); } break; case 3 : if (city.isChecked()) { whereSelect.addItem("Stadt"); }else { whereSelect.removeItem(whereSelect.findText("Stadt")); } break; case 4 : if (street.isChecked()) { whereSelect.addItem("Strasse"); }else { whereSelect.removeItem(whereSelect.findText("Strasse")); } break; case 5 : if (firstName.isChecked()) { whereSelect.addItem("Vorname"); }else { whereSelect.removeItem(whereSelect.findText("Vorname")); } break; case 6 : if (lastName.isChecked()) { whereSelect.addItem("Nachname"); }else { whereSelect.removeItem(whereSelect.findText("Nachname")); } break; case 7 : if (male.isChecked()) { whereSelect.addItem("Anrede"); }else { whereSelect.removeItem(whereSelect.findText("Anrede")); } break; case 8 : if (roll.isChecked()) { whereSelect.addItem("Rolle"); }else { whereSelect.removeItem(whereSelect.findText("Rolle")); } break; case 9 : if (companyName.isChecked()) { whereSelect.addItem("Firma"); }else { whereSelect.removeItem(whereSelect.findText("Firma")); } break; case 10 : if (phone.isChecked()) { whereSelect.addItem("Telefon"); }else { whereSelect.removeItem(whereSelect.findText("Telefon")); } break; case 11 : if (mail.isChecked()) { whereSelect.addItem("E-Mail"); }else { whereSelect.removeItem(whereSelect.findText("E-Mail")); } break; } } void ViewQuerryOption::okPushed() { if (nameOfV.text()=="") { const wchar_t* QboxText = L"Bitte geben Sie einen Namen für die neue Ansicht ein!\n"; msgBox.setWindowTitle("Name fehlt"); msgBox.setIcon(QMessageBox::Warning); msgBox.setText(QString(QString::fromWCharArray(QboxText))); msgBox.exec(); }else if(localTmpMap->contains(nameOfV.text())) { /*ModulQuery foo; foo = localTmpMap->value(nameOfV.text()); cout <<"Querry: " <<foo.getQuery().toStdString() <<endl; */ const wchar_t* QboxText = L"Dieser Name existiert bereits! Bitte wählen Sie einen anderen.\n"; msgBox.setWindowTitle("Name existiert"); msgBox.setIcon(QMessageBox::Warning); msgBox.setText(QString(QString::fromWCharArray(QboxText))); msgBox.exec(); }else { this->createQuery(); this->close(); } } /* * Übernimmt die Zeiger auf den Querry und den Tabnamen auf Klasseenvariablen * und startet die View. */ void ViewQuerryOption::tableViewOption(QString *query, QString *viewName, QMap <QString, ModulQuery> *TqmStorage) { makingQuery=query; localViewName=viewName; localTmpMap = TqmStorage; this->exec(); } /* * Erstellt aus den ANgaben des Nutuzers einen gültigen SQL Query */ void ViewQuerryOption::createQuery() { *makingQuery="SELECT"; if (plz.isChecked()) {*makingQuery=*makingQuery+" plz,";} if (number.isChecked()) {*makingQuery=*makingQuery+" hausnummer,";} if (city.isChecked()) {*makingQuery=*makingQuery+" ort,";} if (street.isChecked()) {*makingQuery=*makingQuery+" strasse,";} if (firstName.isChecked()) {*makingQuery=*makingQuery+" vorname,";} if (lastName.isChecked()) {*makingQuery=*makingQuery+" nachname,";} if (male.isChecked()) {*makingQuery=*makingQuery+" anrede,";} if (roll.isChecked()) {*makingQuery=*makingQuery+" rollenname,";} if (companyName.isChecked()) {*makingQuery=*makingQuery+" firmenname,";} if (phone.isChecked()) {*makingQuery=*makingQuery+" telefonnummer, beschreibung,";} if (mail.isChecked()) {*makingQuery=*makingQuery+" mail,";} //löscht das letzte Komma bevor FROM geschrieben wird. SQL Fehler vermeiden! makingQuery->remove((makingQuery->length()-1),1); *makingQuery=*makingQuery+" FROM"; if (plz.isChecked() || number.isChecked() || city.isChecked() || street.isChecked()) {*makingQuery=*makingQuery+" dm_anschrift,";} if (firstName.isChecked() || lastName.isChecked() || male.isChecked()) {*makingQuery=*makingQuery+" dm_person,";} if (phone.isChecked()) {*makingQuery=*makingQuery+" dm_phone,";} if (mail.isChecked()) {*makingQuery=*makingQuery+" dm_mail,";} //löscht das letzte Komma vor WHERE geschrieben wird. SQL Fehler vermeiden! makingQuery->remove((makingQuery->length()-1),1); if (whereSelect.currentText()=="Suche verfeinern") { }else { *makingQuery=*makingQuery+" WHERE "; *makingQuery=*makingQuery+whereSelect.currentText(); *makingQuery=*makingQuery+relation.currentText(); *makingQuery=*makingQuery+"'"; *makingQuery=*makingQuery+searcher.text(); *makingQuery=*makingQuery+"'"; } *localViewName=nameOfV.text(); }
BTW.: Ich arbeite hier mit der QT Bibliothek da es sich aber um Speicherfehler handelt dachte ich ein C++ Forum ist geeigneter. Ich weis es ist viel Code, das Meiste sind Form Objekte die in Layouts geschachtelt werden.
Ist die Funktion ein gängiger Workaround oder liegt da schon der Fehler begraben?
void ViewQuerryOption::tableViewOption(QString *query, QString *viewName, QMap <QString, ModulQuery> *TqmStorage) { makingQuery=query; localViewName=viewName; localTmpMap = TqmStorage; this->exec(); }
Vielen Dank schonmal für eure Hilfe!
Gruß Meho
-
Tja, hunderte Codezeilen, aber new und delete einfach nur aus dem Zusammenhang gerissen. Das ist ziemlich sinnlos.
Geraten: Qt löscht deine View schon, dein delete ist dann eins zu viel
-
Jepp, Qt löscht nach close():
http://qt-project.org/doc/qt-5/qwidget.html#close
-
Also auf der einen Seite bin ich über eure schnelle und kompetente Hilfe sehr beeindruckt und sehr dankbar!
Auf der anderen Seite sucht, googelt und wühlt man an einem Fehler, stunden lang, den andere in nicht mal 5 min beantwortet haben!Ich führe
this->close();
in "void ViewQuerryOption::okPushed()" aus und erbe von QDialog also passt
"If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted."Vielen Dank für eure schnelle Hilfe!
BTW: Kann ich irgenwie nachvolziehen ob das Objekt gelöscht wurde im Debugger habe ich nichts gefunden, da sieht man nur den Stack.
Gruß Meho
-
Meho schrieb:
BTW: Kann ich irgenwie nachvolziehen ob das Objekt gelöscht wurde im Debugger habe ich nichts gefunden, da sieht man nur den Stack.
Haltepunkt oder Ausgabe im Destruktor
-
Meho schrieb:
Auf der anderen Seite sucht, googelt und wühlt man an einem Fehler, stunden lang, den andere in nicht mal 5 min beantwortet haben!
Oft ist es leider andersrum, viele fragen einfach in Foren nach, ohne auch nur 2 min selbst nachzulesen oder google zu fragen...
-
Meho schrieb:
Also auf der einen Seite bin ich über eure schnelle und kompetente Hilfe sehr beeindruckt und sehr dankbar!
Auf der anderen Seite sucht, googelt und wühlt man an einem Fehler, stunden lang, den andere in nicht mal 5 min beantwortet haben!Das nennt man Erfahrung
Erfahrung gewinnt man (auch), indem man Fehler macht!