Keystone Visual C++ : Seit wann müssen Pointer gelöscht werden ?



  • Hi Leute,

    ich hab ma eine kleine Frage zu den Sachen, die in Keystone Visual C++ beigebracht werden. In einen der Videos wird in eine Datenbank ein Eintrag angelegt, wobei dieser Code hier verwendet wird :

    CStudent *pS;
    	POSITION pos = m_StudentList.GetHeadPosition();
    	while (pos != NULL) {
    		pS = (CStudent*) m_StudentList.GetNext(pos);
    		delete pS;
    	}
    	m_StudentList.RemoveAll();
    

    So, meine Frage dazu wäre, warum er den Pointer pS löscht ?
    Seit wann muss/kann man Pointer löschen?
    Der Pointer muss doch nur gelöscht werden, wenn er mit new erstellt wird, was in diesem Fall nicht gemacht wird.

    Meiner Meinung nach, wäre dieser Code hier richtig :

    CStudent *pS = new CStudent(); // < ------ HIER 
    	POSITION pos = m_StudentList.GetHeadPosition();
    	while (pos != NULL) {
    		pS = (CStudent*) m_StudentList.GetNext(pos);
    		delete pS;
    	}
    	m_StudentList.RemoveAll();
    

    Danke für alle Tipps...

    Peace21



  • Wo wird denn die Liste gefüllt?



  • Naja, ich meine allgemein das dort eine Datenbank gefüllt wird.
    ....



  • m_StudentList enthält offentsichlich Pointer auf CStudent.
    Diese wurden irgendwann vermutlich auch mal mit new erstellt.
    Deswegen kann/muss man sie auch mit delete Löschen, sofern man
    sie nicht mehr benötigt.



  • Redhead schrieb:

    m_StudentList enthält offentsichlich Pointer auf CStudent.
    Diese wurden irgendwann vermutlich auch mal mit new erstellt.
    [...]

    Wegen dem vermutlich frage ich ja. 🙂



  • Hmm, also so weit ich alles verfolgen konnte, erstellt er nur zu diesen Zeitpunkt einen Pointer aus CStudent...

    Naja..



  • Naja, ich meine allgemein das dort eine Datenbank gefüllt wird.
    ....



  • Kannst du jetzt bitte die Scheuklappen abnehmen und mal im Rest des Quellcodes nachgucken, wo denn die Studenten in die Liste gesteckt werden? 🙄

    Das Programm besteht aus mehr als diesen paar von dir geposteten Zeilen - wenn nicht, dann wird es für immer ein Rätsel bleiben, wo denn die kleinen Studenten herkommen... 🤡

    Edit:
    Oh, den bösen Irrtum im zweiten Beispiel habe ich erst jetzt gesehen. Das zusätzliche new würde Speicherlecks verursachen. Lies mal: http://www.c-plusplus.net/forum/viewtopic-var-t-is-103523-and-highlight-is-rottet.html



  • Es ist doch völlig egal wo die Studenten instanziert werden. Warum? Weil folgendes entscheidend bzw. der Grund ist, weshalb ein delete gemacht werden soll:

    m_StudentList.RemoveAll();
    

    Das ist eine Liste die zum Schluss geleert wird. Da die Objekte aber nicht autom. deleted werden, wenn man RemoveAll() aufruft, macht es Programmierer selbst, wenn er eh alle Studenten vorher durchläuft.

    So, was wäre aber, wenn dieses RemoveAll nicht aufgerufen werden würde? Dann würde man kein delete machen, weil es keinen Grund gibt.



  • Wenn man die Liste nicht löschen will macht es auch keine Sinn sie sie löschen.
    Dies ist aber ein Code der die Liste löscht und somit die Objekte in Ihr. Da diese Objekte aber Zeiger auf Studenten sind muss man diesen Speicher auch freigeben.

    Der Frager hat hier ein Grundlagenproblem.
    Er glaubte das
    CStudent pS;
    bereits eingültiger Zeiger wäre und
    pS = (CStudent
    ) m_StudentList.GetNext(pos);
    auch etwas drinsteht.

    Er war der Meinung das dieser Zeiger aus dem Nichts kommt und somit auch nicht gelöscht werden muss.

    Er hat übersehen und nicht gepostet wo eigentlich mit new eine Instanz der Klasse CStudent erstellt wird.

    Es ist zur beantwortung somit nicht unerhebnlich im zu Erklären das er mal nachsehen soll wo eigentlich die Instanz der Klasse erstllt wird und diese dann auch in die Liste eingetragen wird.



  • Hey Unix-Tom,

    *pS wird wirklich nicht mit new dynamisch erstellt, dass einzige was ich gefunden habe, was dynamisch erstellt wird, is das hier :

    CStudent *p = new CStudent( dlg.m_strName,dlg.m_strFaculty, dlg.m_nGrade );
    

    Allerdings wird ein Pointer namens *p erzeugt und nicht *pS !

    Mehr gibt es nicht in dem Projekt...

    Peace21



  • Was wird dann mit p gemacht? 🙂

    Namen kann man doch ändern. 😉



  • Dein Denkfehler ist, dass du glaubst, dass ein Pointer gelöscht werden muss. Das ist aber nicht der Fall, gelöscht wird ein Objekt, das mit new erstellt wurde (und dessen Adresse einem Pointer zugewiesen wird). In deinem Beispiel zeigt wohl zuerst p auf eins dieser Objekte, dann wird seine Adresse (= der Wert von p) in eine Liste eingetragen. Später wird die Liste elementweise gelöscht, dabei wird in jedem Knoten die Adresse des entsprechenden Objektes an pS zugewiesen und dort gelöscht.



  • Das sind offensichtlich gravierende Schwächen in den Grundlagen.

    Geh bitte nochmal das Kapitel über Pointer (Zeiger) in deinem Buch durch.
    Sonst wird es dir hier vielleicht ein C++-Profi erklären.
    Hat nichts mit MFC oder VC++ zu tun.



  • Dieser Thread wurde von Moderator/in Unix-Tom aus dem Forum MFC (Visual C++) in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hi,

    @ Baschar
    Nein, ich habe das ganze Projekt abgesucht und keine Zeile gefunden wo pS der Adresse des Pointers p zugewiesen wird.

    Für alle (wie Estartu ;)) die gerne mal in das Projekt schauen möchten, falls
    sie mir nicht glauben (oder ich etwas übersehen habe) ....

    Download:
    http://www.k2theb.ag.vu/sreg.zip

    Hoffe ihr könnt mir meinen Denkfehler/Sehfehler erklären 😉

    Peace21



  • Dann schau doch mal bitte in die Datei "sregDoc.cpp" da steht

    m_StudentList.AddHead(p);
    

    der Zeiger "p" wird übergeben. Vorher wird mit new ein Objekt erzeugt und mit der obigen Zeile in die Liste eingefügt, also muss das erzeugte Objekt auch wieder per delete freigegeben werden. Wie der Zeiger auf das Objekt heißt ist völlig egal. Wenn Dir das jetzt immer noch nicht klar ist, dann nimm bitte Unix-Toms's Rat an und lies Dir noch ein paar Mal das Kapitel über Pointer durch.



  • Mach dir vor allem klar was der Unterschied zwischen einem Objekt und einem Pointer ist...



  • finix schrieb:

    Mach dir vor allem klar was der Unterschied zwischen einem Objekt und einem Pointer ist...

    Genau das werde ich jetzt machen, denn das ist irgendwie das verwirrenste an dieser Sache...

    Danke für all eure Hilfe.
    Peace21



  • Ein zeiger ist einfach eine Adresse, die man auf NULL setzt, wenn damit kein Blödsinn getrieben werden soll, denn dann kann man vorher auf (Pointer == NULL) testen. Ein Objekt wird durch den Konstruktor erzeugt und durch den Destruktor vernichtet. Die Daten des Objekts sind allerdings noch da, daher biegt man die Pointer zur Sicherheit auf NULL um. Man reisst also die Wegweiser auf das Geisterhaus "Totes Objekt" aus der Erde, damit keiner das Haus betritt, bevor ein neuer Mieter einzieht.


Anmelden zum Antworten