Fehlermeldung bei delete

XoR_1337

Mitglied
Guten Abend.
Ich habe heute ein kleines Programm geschrieben, womit ich den Umgang mit der SDL üben wollte.
Klappt soweit auch alles, doch am Ende der Mainfunktion gebe ich alle Zeiger mit delete frei, die ich dort mittels new erstellt habe. Dies hat allerdings eine Fehlermeldung zur Folge, die wie folgt aussieht:

Windows hat einen Haltepunkt in bla.exe ausgelöst.

Dies kann auf eine Beschädigung des Heaps zurückzuführen sein, die auf ein Problem in bla.exe oder in einer der geladenen DLLs hinweist.

Dies kann auch darauf zurückzuführen sein, dass der Benutzer F12 drückt, während bla.exe den Fokus hat.

Weitere Analyseinformationen finden Sie möglicherweise im Ausgabefenster.


Hiernach klicke ich auf "Unterbrechen" und ein weiteres Fenster erscheint:

Es sind keine Symbole für Aufruflistenrahmen geladen. Der Quellcode kann nicht angezeigt werden.

Dort klicke ich nun auf "OK" und beende das Programm über die Entwicklungsumgebung Visual c++.

Erwähnenswert ist noch, dass diese erste Fehlermeldung erst nach manuellem Schließen des Konsolenfensters erscheint, was ich auch komisch finde, da sich normalerweise das Konsolenfenster nach dem schließen des SDL-Fensters automatisch schließt.


Hier noch meine Mainfunktion:
Code:
#include <sdl.h>
#include "Klassen.hpp"


using namespace std;

int main(int argc, char *argv[])
{
	//Game zum laufen bringen
	bool GameRun = true;

	//Framework initialisieren
	g_pFramework->Init(800, 600, 16, false, "Versuch");
	//Hintergrundbild setzen
	g_pFramework->SetBackground("Background.bmp");

	//Event initialisieren
	CEvent *pEvent = new CEvent;

	//Turm erstellen
	CTurm *pTurm = new CTurm(600.0, 75.0);

	//Monster erstellen
	CMonster *pMonster = new CMonster(200.0, 75.0);


	//GAME LOOP
	//
	while(GameRun)
	{
		GameRun = pEvent->LookForEvent();
		g_pFramework->Flip();
	}


	g_pFramework->Quit();
	

	delete(pTurm);
	delete(pMonster);
	delete(pEvent);



	g_pFramework->Del();

	return(0);
}

Die Fehlermeldung erscheint nach Ausführung der Zeile 39. Habe die delete-befehle auch schon ausgetauscht, liegt also nicht explizit an "delete(pTurm)".


Danke Allen schon mal im Vorraus!
MFG XoR_1337
 
Was ist g_pFramework? Und wieso kannst du es benutzen, ohne es zuweisen zu müssen (oder new-en) zu müssen?

Ist g_pFramework nicht initialisiert, hat g_pFramework nur wenige Member, und es wird das erste Mal innerhalb von g_pFramework->Quit() auf eines zugegriffen, dann kann der Zugriff das Problem sein.

Einfachmal mit Debugger starten, der sagt einem relativ genau, wo es hapert.
 
Der Debugger gibt keine Fehlermeldung aus, was ich auch komisch finde.
g_pFramework wurde in der Klasse Framework schon über eine SingletonKlasse definiert.
Wenn ich wieder zuhause bin, werde ich alle verbliebenen Klassen zur besseren Verständlichkeit Posten.
Ich dachte zuerst dass es güngt die Main zu Posten um dem Fehler auf den Grund zu gehen:D.

MFG XoR_1337

EDIT: hier die restlichen Klassen:

Framework.hpp:
Code:
#include <sdl.h>
#include <iostream>
#include "Singleton.hpp"

using namespace std;



#define g_pFramework CFramework::Get()




class CFramework : public TSingleton<CFramework>
{
	public:

		CFramework();
		~CFramework();
		void Init(int Width, int Height, int ColorDepth, bool Fullscreen, const char *WindowName);
		void SetBackground(const char *Background);
		void Update();
		void Flip();
		void Quit();
		SDL_Surface* GetScreen() { return(m_pScreen); }

	private:

		SDL_Surface *m_pScreen;
		SDL_Surface *m_pBackground;
		SDL_Rect m_RectBackground;
};


//####################################################################
//####################### Methoden/Konstruktor #######################
//####################################################################

//------------------------------ CFramework
//
CFramework::CFramework()
{
	//Surfaces auf NULL setzen
	m_pScreen = NULL;
	m_pBackground = NULL;
}



//------------------------------ ~CFramework
//
CFramework::~CFramework()
{
	//Surfaces freigeben
	SDL_FreeSurface(m_pScreen);
	SDL_FreeSurface(m_pBackground);
}




//------------------------------ Init
//
void CFramework::Init(int Width, int Height, int ColorDepth, bool Fullscreen, const char *WindowName)
{
	//SDL initialisieren
	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1)
	{
		cout << "Fehler beim Initialisieren der SDL!" << endl;
		cout << "Fehlermeldung:" << endl;
		cout << SDL_GetError() << endl << endl;
	}


	//Vollbildmodus starten oder nicht
	if(Fullscreen)
	{
		m_pScreen = SDL_SetVideoMode(Width, Height, ColorDepth, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
	}
	else
	{
		m_pScreen = SDL_SetVideoMode(Width, Height, ColorDepth, SDL_HWSURFACE | SDL_DOUBLEBUF);
	}


	//WindowName setzen
	SDL_WM_SetCaption(WindowName, NULL);

}



//------------------------------ SetBackground
//
void CFramework::SetBackground(const char *Background)
{
	//Bild laden und in das Surface speichern
	m_pBackground = SDL_LoadBMP(Background);

	//RectKoordinaten setzen
	m_RectBackground.x = 0;
	m_RectBackground.y = 0;

	//Hintergrundbild anzeigen
	SDL_BlitSurface(m_pBackground, NULL, m_pScreen, &m_RectBackground);
}




//------------------------------ Update
//
void CFramework::Update()
{
	//kommt erst noch
}



//------------------------------ Flip
//
void CFramework::Flip()
{
	//Zeiger auf Backend richten
	SDL_Flip(m_pScreen);
}



//------------------------------ Quit
//
void CFramework::Quit()
{
	//SDL beenden
	SDL_Quit();
}


Singleton.hpp:
Code:
#ifndef SINGLETON_HPP
#define SINGLETON_HPP

template <class T>
class TSingleton
{
  protected:

  // Membervariablen
  static T *m_pSingleton;   // Statisches Objekt

  public:

  // Memberfunktionen


  virtual ~TSingleton () {  }

  //------------------------------ Get
  //
  inline static T* Get ()
  {
    // Instanz vorhanden?
    if (!m_pSingleton)
    m_pSingleton = new T;   // Nein, dann neue erzeugen

    // Zeiger auf die Instanz zurückgeben
    return (m_pSingleton);

  } 



  //------------------------------ Del
  //
  static void Del ()
  {
    // Instanz vorhanden?
    if (m_pSingleton)
    {
      delete (m_pSingleton);  // freigeben
      m_pSingleton = NULL;    // und Zeiger auf NULL setzen
    }

  }

};

// statische Variable erzeugen
//
template <class T>
T* TSingleton<T>::m_pSingleton = 0;

#endif


Sprite.hpp:
Code:
#include <sdl.h>

class CSprite
{
	public:

		CSprite();
		~CSprite();
		void Load(const char *FileName);
		void SetColorKey(int R, int G, int B);
		void Render(float xPos, float yPos);
		void SetPos(float xPos, float yPos);
		SDL_Surface* GetSprite() { return(m_pSprite); };

	private:

		SDL_Surface *m_pSprite;
		SDL_Surface *m_pScreen;
		SDL_Rect m_RectSprite;
};



//####################################################################
//####################### Methoden/Konstruktor #######################
//####################################################################

//------------------------------ CSprite
//
CSprite::CSprite()
{
        //Zeiger auf den "Screen" holen
	m_pSprite = NULL;
	m_pScreen = g_pFramework->GetScreen();
}



//------------------------------ ~CSprite
//
CSprite::~CSprite()
{
        //Surfaces freigeben
	SDL_FreeSurface(m_pSprite);
	SDL_FreeSurface(m_pScreen);
}




//------------------------------ Load
//
void CSprite::Load(const char *FileName)
{
        //Bitmap laden
	m_pSprite = SDL_LoadBMP(FileName);
}



//------------------------------ SetColorKey
//
void CSprite::SetColorKey(int R, int G, int B)
{
        //ColorKey setzen
	SDL_SetColorKey(m_pSprite, SDL_SRCCOLORKEY, SDL_MapRGB(m_pSprite->format, R, G, B));
}



//------------------------------ Render
//
void CSprite::Render(float xPos, float yPos)
{
        //Koordinaten, höhe und Breite des Rects füllen
	m_RectSprite.x = static_cast<int>(xPos);
	m_RectSprite.y = static_cast<int>(yPos);
	m_RectSprite.w = m_pSprite->w;
	m_RectSprite.h = m_pSprite->h;

        //Surface erzeugen
	SDL_BlitSurface(m_pSprite, NULL, m_pScreen, &m_RectSprite);
}



//------------------------------ SetPos
//
void CSprite::SetPos(float xPos, float yPos)
{
        //Rect mit Koordinaten füllen
	m_RectSprite.x = static_cast<int>(xPos);
	m_RectSprite.y = static_cast<int>(yPos);

        //Surface erzeugen
	SDL_BlitSurface(m_pSprite, NULL, m_pScreen, &m_RectSprite);
}


Event.hpp:
Code:
#include <sdl.h>
#include <iostream>

class CEvent
{
	public:

		bool LookForEvent();

	private:

		SDL_Event event;
};



//####################################################################
//####################### Methoden/Konstruktor #######################
//####################################################################


//------------------------------ LookForEvent
//
bool CEvent::LookForEvent()
{
	if(SDL_PollEvent(&event))
	{
		if(event.type == SDL_QUIT)
		{
			return (false);
		}
		else
		{
			return (true);
		}
	}
	else
	{
		return(true);
	}

}


Monster.hpp:
Code:
#include <sdl.h>

class CMonster
{
	public:

		CMonster(float xPos, float yPos);
		~CMonster();


	private:

		CSprite *m_pSpriteMonster;

		int m_health;
};



//####################################################################
//####################### Methoden/Konstruktor #######################
//####################################################################

//------------------------------ CMonster
//
CMonster::CMonster(float xPos, float yPos)
{
	m_pSpriteMonster = new CSprite;

	m_pSpriteMonster->Load("Monster.bmp");
	m_pSpriteMonster->SetColorKey(255, 255, 255);
	m_pSpriteMonster->Render(xPos, yPos);

	m_health = 100;
}



//------------------------------ ~CMonster
//
CMonster::~CMonster()
{
	delete(m_pSpriteMonster);
	m_pSpriteMonster = NULL;
}


Turm.hpp:
Code:
#include <sdl.h>

class CTurm
{
	public:

		CTurm(float xPos, float yPos);
		~CTurm();


	private:

		CSprite *m_pSpriteTurm;

		int m_health;
};



//####################################################################
//####################### Methoden/Konstruktor #######################
//####################################################################

//------------------------------ CTurm
//
CTurm::CTurm(float xPos, float yPos)
{
	m_pSpriteTurm = new CSprite;

	m_pSpriteTurm->Load("Tower.bmp");
	m_pSpriteTurm->Render(xPos, yPos);

	m_health = 100;
}



//------------------------------ ~CTurm
//
void CTurm::~CTurm()
{
	delete(m_pSpriteTurm);
	m_pSpriteTurm = NULL;
}


Klassen.hpp:
Code:
#include "Framework.hpp"
#include "Sprite.hpp"
#include "Event.hpp"
#include "Turm.hpp"
#include "Monster.hpp"


Hoffe nun, dass wer den Fehler findet. Sind einige Klassen ich weiß, und ich entschuldige mich dafür :D
 
Zuletzt bearbeitet:
Habe nun herausgefunden, dass es funktioniert, wenn man in der Klasse Framework die Zeile 56 "SDL_FreeSurface(m_pScreen);" herauslöscht.
Nur ist mir noch nicht ganz klar warum es dann funktioniert. Ich wäre sehr dankbar, wenn mir das einer erklären könnte :)


MFG XoR_1337
 
Hi.

Du versuchst den Screen mehrfach freizugeben.

Einmal in Framework Zeile 56 und auch in Sprite Zeile 45.

Gruß
 
Das war zunächst auch meine Überlegung, doch ich habe 2Objekte, die jeweils eine CSprite-Membervariable haben. Somit wird beim deleten jedes der zwei Objekten auch jeweils der Dekonstruktor von CSprite aufgerufen, in welchen ich m_pScreen freigebe.
Da ich 2Objekte habe, wird also auch hier 2mal m_pScreen durch den Dekonstruktor von CSprite freigegeben und müsste folglich ebenfalls eine Fehlermeldung ausgeben(was es jedoch nicht tut), oder verstehe ich da was falsch?
 
Zurück