Fehler beim Beenden des Programmes



  • Hallo

    Z2 schrieb:

    Stellt sich erst mal die Frage, ob es wirklich nötig ist die anderen Header in Game.h einzubinden. Du könntest immerhin noch versuchen nur Game.h bzw. nur Game.h und Framework.h auszukommentieren. Wenn es beide Mal zu keinem Fehler kommt, liegt der Fehler mit hoher Wahrscheinlichkeit in Game.h (die du uns übrigens bis jetzt verschwiegen hast, wenn ich das richtig sehe).

    Also ich brauche in Game auf jeden Fall Framework.h und Framework braucht Logfile.h
    Hier mal Game.h und Game.cpp:

    #pragma once
    
    #include "GameStateWithMouse.h"
    #include "Text.h"
    #include "Framework.h"
    #include "Sprite.h"
    #include "Cube.h"
    #include "boost/lexical_cast.hpp"
    #include <vector>
    
    class Game : public SDL::GameStateWithMouse
    {
    public:
    	Game(void);
    	~Game(void);
    	void Init(int Start);
    	void Run(void);
    	int Quit(void);
    
    protected:
    	std::vector<Cube> Cubes;
    	int WhichMouseButton;
    	SDL::Sprite Mouse;
    	SDL::Text OPText;
    	void Render(void);
    	void Move(void);
    };
    
    #include "Game.h"
    #include "Timer.h"
    
    using boost::lexical_cast;
    
    Game::Game(void)
    {
    	Cubes.resize(5);
    }
    
    Game::~Game(void)
    {
    }
    
    void Game::Init(int Start)
    {
    	SDL_ShowCursor(SDL_DISABLE);
    	Mouse.Load("Mouse/MouseCursor.bmp");
    	OPText.Init("fonts/FreeSansBold.ttf",22);
    	m_bGameRun = true;
    	for(int i=0; i<5; ++i)
    		Cubes[i].Init(50 + i*185,50);
    
    }
    
    void Game::Run(void)
    {
    	while(m_bGameRun)
    	{
    		SDL::Framework::Get()->Clear();
    		SDL::Framework::Get()->Update();
    		ProcessEvents(&WhichMouseButton);
    		Move();
    		Render();
    		SDL::Framework::Get()->Flip();
    	}
    }
    
    int Game::Quit(void)
    {
    	OPText.Quit();
    	return 1;
    }
    
    void Game::Move(void)
    {
    	Mouse.SetPos(static_cast<float>(m_iMousePosX),static_cast<float>(m_iMousePosY));
    }
    
    void Game::Render(void)
    {
    	OPText.Render("Hallo");
    	for(unsigned int i=0; i<5; ++i)
    		Cubes[i].Render();
    	Mouse.Render();
    }
    

    Ich hoffe, dass das weiterhilft. Ich bin wirklich etwas verzweifelt. Ich würde das Projekt auch mal jemand schicken, damit er es mal bei sich probieren kann.

    chrische



  • Ich sehe jetzt nicht, wo in Game.h irgendetwas aus Framework.h benötigt würde (dito für Framework.h und Logfile.h).

    Der Tip mit dem Single Step durchlauf ist sicher nicht schlecht. Irgendwo geht irgendetwas bei der Destruktion irgendeines Objektes schief und du wirst nicht darum herumkommen herauszufinden, von welcher Klasse dieses Objekt ist. Aus den Headern, die du uns bisher gezeigt hast, läßt sich erstmal nichts weiter erkennen (aber du includierst in diesen Headern ja noch andere Header).

    Nebenbei bemerkt, deine Singleton-Klasse taugt nichts (hab sie mir gerade zum ersten Mal richtig angesehen). Schau dir das am besten noch mal genau an. Der öffentlich zugängliche Desktruktor der Singleton-Klasse und der abgeleiteten Klassen sind ein Problem. Und wenn wir schon mal dabei sind, der öffentlich zugängliche Konstruktor der Singleton-Klasse ist auch nicht gerade schön (ich trau mich kaum den öffentlich zugänglichen Copy-Konstruktor zu erwähnen 😉 ). Instinktiv würde ich mal vermuten, daß die Ursache für dein Problem da irgendwo zu suchen ist (ist aber bloß geraten, Fehler könnte auch an jeder beliebigen anderen Stelle liegen).



  • Hallo

    Ich habe es nun mal mit einem anderem Singleton probiert. Nur leider habe ich davon keine Ahnung und nun sieht es so aus:

    Singleton.h:

    #pragma once
    
    template<class X>
    class TSingleton
    {
    private:
    	TSingleton() {};
    	TSingleton(const TSingleton&) {};
    	virtual ~TSingleton();
    	TSingleton& operator=(const TSingleton&);
    
    	static X* Singleton;
    
    public:
    	static X* Get(void)
    	{
    		if(!Singleton)
    			Singleton = new X;
    		return Singleton;
    	}
    };
    
    template<class X>
    X* TSingleton<X>::Singleton = 0;
    

    Nur bekomme ich jetzt bei den abgeleiteten Klassen immer Fehlermeldung in deren C'tor und D'tor, weil diese nicht privat Member zugreifen können:

    Error 1 error C2248: 'TSingleton<X>::TSingleton' : cannot access private member declared in class 'TSingleton<X>'

    Error 2 error C2248: 'TSingleton<X>::~TSingleton' : cannot access private member declared in class 'TSingleton<X>'

    chrische



  • @chrische
    Du solltest in deinen Headern (und auch ÜE!) erstmal die Stellen suchen, wo globale Instanzierungen erfolgen. Also all das, was noch vor main geschieht. Ansonsten können wir mit deinem geposteten Code nicht viel anfangen. Die Fehlermeldungen deutet jedenfalls auf einen dereferenzierten Nullzeiger hin.



  • Hallo

    groovemaster schrieb:

    @chrische
    Du solltest in deinen Headern (und auch ÜE!) erstmal die Stellen suchen, wo globale Instanzierungen erfolgen. Also all das, was noch vor main geschieht. Ansonsten können wir mit deinem geposteten Code nicht viel anfangen. Die Fehlermeldungen deutet jedenfalls auf einen dereferenzierten Nullzeiger hin.

    Das würde ich sehr gerne machen, wenn di mir erklären könntest, was das ist und wie ich es finde.

    chrische



  • Was meinst du mit "was das ist"? Verstehst du nicht, was globale Instanzierungen sind?



  • Hallo

    groovemaster schrieb:

    Was meinst du mit "was das ist"? Verstehst du nicht, was globale Instanzierungen sind?

    Wenn ich ehrlich bin, dann muss ich diese Frage mit "ja" beantworten.

    chrische



  • Hallo

    Kann mir mal bitte jemand erklären, was globale Instanzierung sind, weil ich dann an meinem Problem weiter arbeiten könnte.

    chrische



  • Ohne jetzt zu sehr ins Detail zu gehen, dein Problem wird von einem Objekt verursacht, das vor Beginn der Ausführung von main() konstruiert und nach Ende der Ausführung von main() destruiert wird (anders wäre es ja wohl auch kaum möglich, da in deinem Testfall deine main-Funktion leer ist).

    Debugger ist eine Möglichkeit da ranzugehen. Eine andere wäre die Suche im Quelltext. Du könntest versuchen alle deine Quelltext-Dateien nach dem Schlüsselwort static zu durchsuchen (dein Editor/deine IDE sollte eigentlich eine Funktion für projektweite Suche haben). Aus der erhaltenen Liste schmeißt du alle Funktionen und alle Zeiger raus. Unter den übrig gebliebenen Funden sollte sich der Übeltäter befinden, vorausgesetzt du verwendest keine globalen Variablen (und wenn du globale Variablen verwendest, dann verdienst du es, daß du den Fehler nicht finden kannst; globale Variablen sind nämlich böse 😉 ).

    P.S.: Deine zweite Singleton-Klasse ist noch schlimmer als die erste. Vielleicht sollte man ein Design Pattern erst mal verstehen, bevor man es benutzt ...?

    Edit: Rechtschreibung



  • Hallo

    Erstmal danke für die Hilfe. Ich habe nun gesucht und drei mal static gefunden. Alle in dem Singleton-Header:

    static T* m_pSingleton;
    
    inline static T* Get()
    		{
    			if(!m_pSingleton)
    				m_pSingleton = new T;
    			return(m_pSingleton);
    		}
    
    static void Del()
    		{
    			if(m_pSingleton)
    			{
    				delete m_pSingleton;
    				m_pSingleton = NULL;
    			}
    

    Ich weiß aber ehrlich nicht, was ich jetzt damit anfagen soll. Ich benutze keine globale Variablen. Die erste Singletonklasse habe ich aus einem Buch 1 zu 1 übernommen und bei der zweiten habe ich versucht deine Vorschläge einfliessen zu lassen, aber ich kenne mich halt nicht damit aus. Kennst du einen guten Link für template Singleton-Klassen. Ich verwende diese auch nur, weil ich es eben praktisch finde. Ich versteh ja auch nicht genau, was hinter den Kulissen von std::string los ist (habe ich mir noch nie angeschaut) und trotzdem verwende ich es.

    Vielen Dank für deine Hilfe. Vielleicht klappt es ja am Ende doch noch.

    chrische



  • Hm, sieht mir nicht danach aus als ob wir hier schon fündig geworden sind. Sicher, daß du wirklich alle Quelltextdatein überprüft hast? (sowohl h als auch cpp)

    Was Singletons angeht, habe ich leider keinen Link zur Hand. Sorry.



  • Hallo

    Ich habe jetzt noch einmla geschaut und es sind wriklich nur diese drei Stellen, an denen mit static gearbeitet wird. Ich schicke dir auch gerne mal das Projekt (natürlich nur, wenn es was hilft und du Lust hast es dir mal anzuschauen)

    chrische



  • Also mich würde es schon reizen den Fehler zu finden.
    Meine E-Mail Adresse findest du in meinem Profil.

    EDIT:Oder,auch nicht.... spacelord1972-AT-gmx.de

    Gruss Spacelord



  • chrische5 schrieb:

    Wenn ich ehrlich bin, dann muss ich diese Frage mit "ja" beantworten.

    Globale Instanzierungen sind jene Instanzierungen, die auf Namensraumebene stattfinden. Deren Konstruktion also vor main und Destruktion nach main erfolgt.
    ZB:

    foo a; // <- global
    int funktion()
    {
        foo b; // <- lokal
        static foo c; // <- global (zwar nur lokal sichtbar, aber eben globale Lebensdauer)
    }
    
    class bar
    {
        static foo d;
    };
    
    foo bar::d; // <- global
    

    Bei static Instanzierungen innerhalb von Funktionen (im Beispiel mit c) schreibt der Standard zwar vor, dass erst beim ersten Aufruf die Konstruktion erfolgt. Inwiefern sich aber jeder Compiler daran hält, kann ich nicht beurteilen. Solche Stellen wären daher möglichst auch zu untersuchen.



  • Hallo

    @Groovemaster:

    Vielen Dank für die Erklärung. Ich habe das Projekt nun mal an Spacelord geschickt und er will es sich mal anschauen. Wenn ich beziehungsweise er mehr weiß, werde ich mich wieder hier melden.

    Ich habe nur drei static im Projekt und mit den habe ich auch schon vorher ohne Probleme gearbeitet.

    chrische





  • Setz doch mal nen breakpoint in die Konstruktoren...



  • Hallo

    Braunstein schrieb:

    Hier noch was zum Lesen über Singletons
    http://www.oop-trainer.de/Themen/Singleton.html
    http://www.haiko-emmel.de/Single.htm

    Wenn ich das richtig sehe, dann entspricht das template-Beispiel in dem zweiten Link doch fast genau dem, für das ich hier so harte Kritik 😉 einstecken musste.

    templäd schrieb:

    Setz doch mal nen breakpoint in die Konstruktoren...

    Das vesteh ich nicht richtg. Der Fehler tritt doch auf, wenn das Programm sich beendet.

    chrische



  • Ja richtig. Die Vermutung ist doch, dass irgendein Destruktor das Problem macht.
    Aber man weiß nicht wo ein Objekt instanziiert wird.
    Wenn man im Konstuktor stehen bleibt kann man im Calstack nachkucken woher er kommt.



  • chrische5 schrieb:

    Hallo

    Braunstein schrieb:

    Hier noch was zum Lesen über Singletons
    http://www.oop-trainer.de/Themen/Singleton.html
    http://www.haiko-emmel.de/Single.htm

    Wenn ich das richtig sehe, dann entspricht das template-Beispiel in dem zweiten Link doch fast genau dem, für das ich hier so harte Kritik 😉 einstecken musste.

    Hab den zweiten Link jetzt nur überflogen. Aber was ich da gesehen habe ist IMHO extrem schlecht (selbst wenn wir die Sache mit den Makros vergessen; ich gehe mal davon aus, daß die nicht ernst gemeint sind). Zweck des Singleton-Patterns ist es im Allgeminen die Instanzen einer Klasse auf maximal ein Objekt zu beschränken.

    Dieser Zweck wird in dem Moment verfehlt, wo ein öffentlicher Konstruktor existiert. Und das ist wirklich nur die Spitze des Eisberges.

    Ich will nicht sagen, daß man die angegebenen Klassen nicht als Singleton einsetzen könnte, aber es mangelt ihnen allesamt an Robustheit, d.h. es ist viel zu einfach damit durch geringfügige Fehler bei der Benutzung Bugs zu erzeugen (es gibt bei den verschiedenen Beispielen unter anderem Probleme beim Aufräumen und zum Teil ist auch die Exception-Sicherheit nicht ohne das Betreiben von zusätzlichem Aufwand gegeben).

    chrische5 schrieb:

    templäd schrieb:

    Setz doch mal nen breakpoint in die Konstruktoren...

    Das vesteh ich nicht richtg. Der Fehler tritt doch auf, wenn das Programm sich beendet.

    chrische

    Ja schon, aber indem die feststellst, ich welchen Konstruktor das Programm hineingeht, könntest zu zumindest mal ermitteln, wo da überhaupt was konstruiert wird (ist aus dem bisher gezeigten nicht ersichtlich).


Anmelden zum Antworten