delete == equal to function end?



  • Hm jetzt wo ich anfange die Objekte zu löschen und daraus normale Vars zu machen kommt diese Fehlermeldung -.-

    HEAP[LCM.exe]: Invalid Address specified to RtlFreeHeap( 003E0000, 0012D204 )



  • Hallo KT_Adi,
    was 314159265358979 schreibt ist richtig.
    Ich habe den Verdacht, dass Du Dich mal mit dem "stack" und dem "heap" vertraut machen solltest (Google: "C++ stack heap"). Auch wunder ich mich über "normal angelegte globale-Variablen".
    Wenn ein (Dein?) Destruktor nicht 'aufgerufen' wird (ich nehme an, du hast dort einen Breakpoint oder sonstiges eingebaut), kannst Du davon ausgehen, dass das Objekt (Du?) nicht aus dem Speicher entfernt wird. Entweder ein vergessenes 'delete' oder eine Vererbung ohne virtuelle Methode; dann wird bei einem delete der Unterklasse ggf. der Destruktor der Oberklasse nicht abgearbeitet.
    Gruß
    Helmut



  • Ohwe ohwe -.- ich bekomms ja net mal hin das mein Prog wieder so geht wie mit den ganzen new dingern.

    jedoch hatte ich bisher bei sogesehen 316 new deklarationen nicht ein delete und mein prog lief eig. echt super 😃 was sich im speicher getan hat will ich dann wohl nciht sehen xD.

    Aber nun da ich das new ausmertzen sollte kommt eben die message von meinem letzten post.

    Ich weiß net woher das nun wieder kommt. Aber ich muss ab und an wenn ich zum Beispiel ein Layout generiere ein zB. QLabel so übergeben:

    QLabel stateLabel;
    stateLabel.setText("boing");

    QGridLayout stateAndRev;
    stateAndRev.addWidget(&stateLabel,0,0);

    Hier wird so wies scheint der &-Operator gewünscht. Der zeigt doch eig. nur die Speicher-Adresse von stateLabel an oder?

    Könnte daher diese Fehlermeldung kommen?

    Oder vllt daher das wenn ich ein Texteingabefeld erstelle und dazu sage:
    gnummerShow.setStyle(new QPlastiqueStyle);
    Hier wird ja auch ein new verwendet... 😞 ich bin grad echt ratlos was ich machen soll.

    Vllt doch klüger überall das delete zu setzen? Aber da mein Destruktor iwie nicht will müsste ich ja in jeder Funktion ein delete machen wo ein new steht. Aber da ich solche Varibalen ja in mehreren aufeinanderfolgenden Funktionen nutze würde ein delete doch das nutzen der Variable in darauf folgenden Funktionen zunichte machen?



  • Wie Tachyon schon geschrieben hat, werden Widgets automatisch gelöscht (mittels delete), wenn diese einem Parent zugeordnet wurden (z.B. per addWidget(...)) und müssen somit zwingend mit 'new' auf dem Heap angelegt werden. Der Vorteil ist dann aber, daß du selber kein 'delete' mehr aufrufen brauchst.

    Siehe dir auch die Beispiele unter http://doc.qt.nokia.com/latest/widgets-tutorial.html an (unter "Simple widget examples") - dort gibt es nur 'new' bei den Child-Widgets aber kein 'delete'.

    Für alle anderen Qt-Klassen kannst du (insbesondere wenn du sie nur lokal in einer Funktion brauchst) diese dann einfach direkt auf dem Stack anlegen, z.B.:

    QDir dir;
    
    QFile cZipFile("LCMNID_" + nidout + ".zip");
    


  • Das was Tachyon schreibt gilt noch immer. Diese automatisch gelöschten children beziehen sich nur auf QObject und deren Derivate. So wird auch ein Layout und die darin befindlichen Widgets automatisch zerstört.

    Du läufst aktuell noch in ein anderes Problem: Du erzeugst in Methoden Variablen auf dem Stack, die am Ende wieder zerstört werden, obwohl sie weiter existieren sollten (dein Qlabel, QGridLayout).
    Bei den meisten QWidgets, die via Layouts verwaltet werden, sollte man weiterhin alles im Freispeicher allokieren.



  • Dank Th69 und Tachyon versteh ich das mit den Objekten nun wenigstens 😃 JEDOCH, ist mein Problem das mein Programm ein QMainWindow ist und dises zeigt eben jeweils eins von 2 QWidget an. Ich shifte also zwischen beiden hin und her. Das dumm ist das ich iwie immer wieder nen HEAP[LCM.exe]: Invalid Address specified to RtlFreeHeap( 003E0000, 00A03188 ) Error bekomme -.-.

    Ich hab zwar bisher nur das eine Widget so abgestimmt das überall die Childs wie gehabt als new (sprich Objekt) geschrieben werden nur das Widget normal weil das als Parent ja automatisch alle Childs mit ins Grab nimmt.

    das ohne new:
    QWidget printWidget;

    das mit new:
    QWidget *p_searchWidget;
    p_searchWidget = new QWidget;

    Aber da ich glaube zwischen den Widgets switch kommt eben dieser Error vor wenn ich von dem printWidget in das p_searchWidget gehen will.

    Jedoch von p_searchWidget in das printWidget funktioniert. da zerstör ich ja das p_searchWidget noch nicht mit nem delete...

    Hier is mal das printWidget, hoffe es ist nciht zu viel Code:

    void CKtGekkoLCM::gekkoSN()
    {
    	qDebug() << "gekkoSN";
    
    	QLabel *p_gLabel = new QLabel("G-Nummer: ");
    		p_gLabel->setFont(QFont("Verdana", 12));
    	QLabel *p_revLabel = new QLabel("Revision:    ");
    		p_revLabel->setFont(QFont("Verdana", 12));
    	QLabel *p_seperator = new QLabel(" ");
    		p_seperator->setFixedSize(30,100);
    	QLabel *p_seperator2 = new QLabel(" ");
    		p_seperator2->setFixedSize(250,50);
    	QLabel *p_navLabelT = new QLabel("Connected\n to GekkoSN");
    	QLabel *p_navLabelF = new QLabel("Not connected\n to GekkoSN!");
    	QLabel *p_navTPix = new QLabel;
    		p_navTPix->setPixmap(QPixmap(dir.currentPath() + "/images/NavConTrue.png"));
    	QLabel *p_navFPix = new QLabel;
    		p_navFPix->setPixmap(QPixmap(dir.currentPath() + "/images/NavConFalse.png"));
    	QLabel *p_gekkoPix = new QLabel;
    		p_gekkoPix->setPixmap(QPixmap(dir.currentPath() + "/images/snGekko.png"));
    	QLabel *p_printerPix = new QLabel;
    		p_printerPix->setPixmap(QPixmap(dir.currentPath() + "/images/printer.png"));
    
    	p_printBtn = new QPushButton("Print Label");
    	p_printBtn->setFixedSize(135, 40);
    	p_printBtn->setStyle(new QPlastiqueStyle);
    	p_printBtn->setFont(QFont("Verdana", 12, QFont::Bold));
    
    	p_gNumber = new QLineEdit("");
    	p_gNumber->setStyle(new QPlastiqueStyle);
    	p_gNumber->setStyleSheet("background-color: white");
    	p_gNumber->setFixedSize(115,25);
    
    	p_revNumber = new QLineEdit("");
    	p_revNumber->setStyle(new QPlastiqueStyle);
    	p_revNumber->setStyleSheet("background-color: white");
    	p_revNumber->setFixedSize(115,25);
    
    	QGridLayout *p_layerOne = new QGridLayout;
    	p_layerOne->addWidget(p_gLabel,    1, 0, Qt::AlignLeft);
    	p_layerOne->addWidget(p_gNumber,   1, 1, Qt::AlignLeft);
    	p_layerOne->addWidget(p_seperator, 1, 2, Qt::AlignLeft);
    
    	//navDB.open();
    
    	if(navDB.isOpen())
    	{
    		p_layerOne->addWidget(p_navTPix,   1, 4, Qt::AlignLeft);
    		p_layerOne->addWidget(p_navLabelT, 1, 3, Qt::AlignLeft);
    		delete p_navFPix;
    		delete p_navLabelF;
    	}
    	else
    	{
    		p_layerOne->addWidget(p_navFPix,   1, 4, Qt::AlignLeft);
    		p_layerOne->addWidget(p_navLabelF, 1, 3, Qt::AlignLeft);
    		delete p_navTPix;
    		delete p_navLabelT;
    	}
    
    	QGridLayout *p_layerTwo = new QGridLayout;
    	p_layerTwo->addWidget(p_revLabel,   0, 0, Qt::AlignLeft);
    	p_layerTwo->addWidget(p_revNumber,  0, 1, Qt::AlignLeft);
    	p_layerTwo->addWidget(p_seperator2, 0, 2, Qt::AlignLeft);
    
    	QGridLayout *p_layerThree = new QGridLayout;
    	p_layerThree->addWidget(p_printBtn,   0, 0, Qt::AlignLeft);
    	p_layerThree->addWidget(p_printerPix, 0, 1, Qt::AlignLeft);
    	p_layerThree->addWidget(p_gekkoPix,   0, 5, Qt::AlignLeft);
    
    	QVBoxLayout *p_finalLayout = new QVBoxLayout;
    	p_finalLayout->addLayout(p_layerOne);
    	p_finalLayout->addLayout(p_layerTwo);
    	p_finalLayout->addLayout(p_layerThree);
    
    	//printWidget = new QWidget;
    	printWidget.setLayout(p_finalLayout);
    	printWidget.setWindowModality(Qt::ApplicationModal);
    
    /* Actions for menuBar */
    	p_actionSwitch->setText("Switch to GekkoLCM");
    
    	p_toolsMenu->removeAction(p_actionPasteLCM);
    	p_toolsMenu->removeAction(p_actionPrintLCM);
    
    	p_toolsMenu->addAction(p_actionReprintSN);
    
    	p_menubar->addAction(p_toolsMenu->menuAction());
    
    	connect(p_actionReprintSN,SIGNAL(triggered()),this, SLOT(reprintLabel()));
    	connect(p_printBtn,SIGNAL(clicked()),this, SLOT(useSlpDLL()));
    
    	this->setWindowTitle("GekkoSN - LabelPrinter");
    	this->move(QPoint(400,50));
    	this->setFixedSize(470,185);
    	this->setMenuBar(p_menubar);
    	this->setCentralWidget(&printWidget);
    	this->show();
    }
    


  • KT_Adi schrieb:

    Das dumm ist das ich iwie immer wieder nen HEAP[LCM.exe]: Invalid Address specified to RtlFreeHeap( 003E0000, 00A03188 ) Error bekomme -.-

    Lass das Programm doch einfach mal in einem Debugger oder Profiler laufen, die werden dir sagen, an welcher Stelle der illegale Zugriff geschieht. Bist du dir z.B. sicher, dass das printWidget einfach so zerstört werden darf? Übernimmt dein mainWindow nicht über this->setCentralWidget(&printWidget); den Besitz und zerlegt es dann selbst? Selbst wenn nicht. Wer stellt sicher, dass auf das CentralWidget nicht mehr zugegriffen wird, nachdem deine Methode verlassen wurde (und das Widget dadurch zerstört)?



  • Ich möchte ja nicht unken, aber wäre es nicht eine unabdingbare Anforderung, um u.a. mit QT arbeiten zu können, dass der Unterschied von Stack- und Heap-Objekten bekannt ist?



  • QMainWindow::setCentralWidget() macht das übergebene QWidget wieder zu nem child. Wenn dieses im automatischen Speicherberiech ("Stack") abgelegt ist, wird es zweimal zerstört: einmal eben automatisch, das andere mal vom parent. Das zweite mal gehts halt schief.



  • @Helmut.Jakoby:

    Ja eig. hast du ziemlich Recht, aber ich erlerne hier alles von alleine und bin eben nicht so tief in die Materie zu beginn. Ich bin einer Learning by Doing und so kommts ja auch 😃

    @Lulle:
    Joa is dann ja nen parent vom Mainwindow und wird dann eben 2x zerstört. Ich habs nun eben so geregelt das ich abfrage welches Widget grade Sichtbar ist und dann zerstör ich das nicht Childwidget und das Childwidget wird ja durch den parent eliminiert 😉

    Danke euch allen denke ich hab es nun alles geklärt 😃

    peace


Anmelden zum Antworten