WinMain LifeCycle



  • SammyRukka schrieb:

    (...)

    Code habe ich weggelassen, weil sich der auf sooooo viele Klassen verteilt:D, kann ich aber nachholen.

    Wenn Du so intensiv mit Klassen, Konsturktoren, Destruktoren usw. hantierst, ist es wohl eher eine Frage für MFC oder C++ :p

    Ich dachte new() bedeutet Speicher auf dem Heap -> selbst abzuräumen, bzw. bei Programmende? Ist das falsch?

    Ja. Wenn das Programm beendet wird, wird der Speicher vom Betriebssystem sowieso freigegeben. Das Abräumen muß während des Programmablaufs passieren, damit Dein Heap nicht mit Speicherleaks verstopft wird.



  • Wenn du nicht den gesamten Quelltext zeigen willst, kannst du ihn auf auf die wesentlichen Punkte zusammenfassen.

    Vor allem: welches Objekt legst du per new an - und was genau machst du mit dem Zeiger, den du zurückbekommen hast?



  • OK. Ist wohl doch einfacher, wenn ich das poste. Aber ich kann ja mal kurz zusammenfassen, weil ich zum Code erste heute spät komme:

    WinMain():

    MeinProgramm myProg = MeinProgramm();
    myProg.init();
    myProg.mainLoop();
    
    return 0;
    

    MeinProgramm::init():
    Ruft einen Parser auf, der ein 'Objektnetz' per new instanziiert, das das im ersten Post beschrieben ist.
    MeinProgramm kennt die 'Ankerpunkte' per Pointer (meine ich).

    Das ganz ist funktioniert anscheinend auch, allerdings nur so lange, bis init() fertig ist. Dann springt er in den Destruktor meines (per new()) angelegten Listenobjekts. Falls das nicht reicht, kommt Code 😉 thx, so far!
    PS: Aber immerhin scheint der Destruktor wieder ordentlich aufzuräumen 😉



  • Ich glaube, da benötigen wir doch den Code der init-Methode.



  • CStoll schrieb:

    Ich glaube, da benötigen wir doch den Code der init-Methode.

    OK, kommt Zeit, kommt Code.



  • So, hier die Code-Schnipsel:

    WinMain()

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
    {
    	MeinProgramm myProg = MeinProgramm();
    	myProg.init();
    	myProg.mainLoop();
        return 0;
    }
    

    MeinProgramm.h (Ausschnitt)

    private:
    	MeineListe* a_liste;
    

    MeinProgramm.cpp:

    void MeinProgramm::init() {
    	IniParser l_parser = IniParser();
    	MeineListe l_liste = l_parser.erzeugeListe();
    	a_liste = &l_liste;
            // ...und noch mehr
    }
    

    MeineListe.h:

    class MeineListe {
    public:
    	int a_anzahl;
    	Element* a_liste;
    
    	MeineListe();
    	MeineListe(int p_anzahl); // der wird benutzt!
    	~MeineListe();
    };
    
    MeineListe.cpp:
    MeineListe::MeineListe(int p_anzahl) {
    	a_anzahl = p_anzahl;
    	a_liste = new Element[p_anzahl];
    }
    
    MeineListe::~MeineListe() {
    	// Elemente auch abraeumen? Wie?!
    	delete a_liste;
    }
    

    Ausschnitt IniParser:

    MeineListe& IniParser::erzeugeListe() {
    
            // ....diverses....
    
    	MeineListe* l_liste = new MeineListe(l_anzahl);
    
    	for (int i = 0; i < l_anzahl; i++) {
                    // ....diverses....
    	        Element* l_element = new Element();
    		l_liste->a_liste[i] = *l_element;
    	}
    
    	return *l_liste;
    }
    

    Bei init()-Ende wird der Destruktor von MeineListe aufgerufen. mainLoop() sollte also egal sein.



  • MeinProgramm myProg();



  • MeinProgramm myProg;



  • Welches ist jetzt die (?) Lösung und wenn das eine Lösung ist, kann mir das jemand erklären? Thx!



  • Erstmal (nur am Rande) ist 'MeinProgramm myProg;' als Variablendefinition völlig ausreichend.

    Zweitens:

    void MeinProgramm::init() {
        IniParser l_parser = IniParser();
        MeineListe l_liste = l_parser.erzeugeListe();
        a_liste = &l_liste;
            // ...und noch mehr
    }
    

    Du legst eine lokale Kopie der Liste an, die von erzeugeListe() geliefert wurde und gibst deren Adresse zurück. Das bedeutet einerseits ein Speicherleck (nach der Initialisierung von l_liste hast du keinen Zugriff mehr auf den mit new angeforderten Speicher) und andererseits undefiniertes Verhalten (du übergibst die Adresse eines Objekts, das nicht mehr existiert). Die Lösung dazu liegt in einem Zeichen: 'MeineListe**&** l_liste = ...;'



  • @CStoll: Danke soweit, ich werde das mal sacken lassen und in einer ruhigen Minute 'nacharbeiten'. Evtl. Verständnisfragen kommen dann....
    Zwei habe ich aber jetzt schon:
    1. Macht es einen Unterschied, welche der Varianten ich benutze?!

    MeinProgramm myProg = MeinProgramm();
    MeinProgramm myProg();
    MeinProgramm myProg;
    

    2. Dann war ich mit der Referenz als Rückgabe von 'erzeugeListe' ja schon ganz gut...

    MeineListe& IniParser::erzeugeListe() { ...}
    

    .
    Das hätte ich dann nur ordentlich nutzen müssen und lokal - also in init() - auch mit der Referenz und nicht mit dem Pointer arbeiten müssen.
    Hab ich das richtig verstanden? Wenn ja, dann funktionierte das trotzdem, weil der Compiler mir die Konvertierung selbständig abgenommen hat (Referenz -> Pointer)?!

    Aber ersteinmal: Danke!


Anmelden zum Antworten